编写三个方案过程来模拟这三个门:AND、OR 和 XOR



到目前为止,我假设最后两个应该是:

(define or-gate
  (lambda (a b)
    (if (= a 1)
        1
        (if (= b 1)
            1
            0))))
(define xor-gate
  (lambda (a b)
    (if (= a b)
        0
        1)))

。但 AND 令人费解。我该如何实现它?

如果我们记住=可以接受两个以上的参数,这很简单:

(define and-gate
  (lambda (a b)
    (if (= a b 1)
        1
        0)))

换句话说:and逻辑连接器是true当且仅当它的两个参数都true,对于所有其他参数,它是false

and的真值表是什么? 实际上,如果您有andorxor中的任何一个真值表,那么算法是相同的。

让我们创建一个接受真值表并返回一个计算门逻辑的函数的函数

(define (gate-logic-for-truth-table table)
  (lambda (a b)
    (vector-ref (vector-ref table b) a)))

现在,使用and的真值表,我们生成and-gate函数:

(define and-gate (gate-logic-for-truth-table
                  '#(#(0 0)
                     #(0 1))))

还有一个小型测试:

> (and-gate 0 0)
0
> (and-gate 0 1)
0
> (and-gate 1 0)
0
> (and-gate 1 1)
1

假设参数10

对于or,您无需查看a是否1 b - 结果是 1 。否则,结果为 b
对于and,您无需查看b a是否0 - 结果是0。否则,结果b .

如果你想让它尽可能类似于or-gate,你可以在外部条件中用 0 s 替换 1 s:

(define and-gate
    (lambda (a b)
        (if (= a 0)
            0
            (if (= b 1)
                1
                0))))

或者,如果你想坚持与1进行比较,你可以重新排列分支:

(define and-gate
    (lambda (a b)
        (if (= a 1)
            (if (= b 1)
                1
                0)
             0)))

可以缩短代码:

(define and-gate
    (lambda (a b)
        (if (= a 1)
            b
            0)))

(define or-gate
    (lambda (a b)
        (if (= a 1)
            1
            b)))

但这是否更具可读性是相当个人化的。

如果我们要使用门,我们可能应该从定义一个构造它们的方法开始。我的意思是,我们将不得不建造三个门。

#lang racket
;; Gate Constructor
(define (make-gate predicate)
  (lambda (A B)
    (predicate A B)))

然后,我们可以使用一厢情愿的想法在高层次上定义门:

(define and-gate
  (make-gate and-predicate))
(define or-gate
  (make-gate or-predicate))
(define xor-gate
  (make-gate xor-predicate))

然后我们可以任意定义内部门逻辑,无论我们喜欢什么:

(define (and-predicate A B)
  (let ([a (if A 1 0)]
        [b (if B 1 0)])
    (= 2 (+ a b))))
(define (or-predicate A B)
  (let ([a (if A 1 0)]
        [b (if B 1 0)])
    (< 0 (+ a b))))
(define (xor-predicate A B)
  (let ([a (if A 1 0)]
        [b (if B 1 0)])
    (= 1 (+ a b))))

然后我们做真正的测试工作...好吧,也许我们实际上应该从编写测试开始。

(module+ test
  (require rackunit
       rackunit/text-ui)
  (define (make-test-harness test-function)
    (define (test-harness ins outs)
      (if (or (null? ins)
              (null? outs))
      'test-complete
      (begin
        (test-function (first ins)
                       (first outs))
        (test-harness (rest ins)
                      (rest outs)))))
    test-harness))
  (define gate-inputs
    '((#f #f)
      (#t #f)
      (#f #t)
      (#t #t)))
  (define and-truth-table
    '(#f #f #f #t))
  (define or-truth-table
    '(#f #t #t #t))
  (define xor-truth-table
    '(#f #t #t #f))

  (define (make-gate-test gate name)
    (lambda (input correct)
      (define A (first input))
      (define B (second input))
      (test-equal? name
                   (gate A B)
                   correct)))
  (define and-gate-test
    (make-gate-test and-gate "AND Gate Test"))
  (define or-gate-test
    (make-gate-test or-gate "OR Gate Test"))
  (define xor-gate-test
    (make-gate-test xor-gate "XOR Gate Test"))
  (define (and-tests)
    (define tests
      (make-test-harness and-gate-test))
    (tests gate-inputs and-truth-table))
  (define (or-tests)
    (define tests
      (make-test-harness or-gate-test))
    (tests gate-inputs or-truth-table))
  (define (xor-tests)
    (define tests
      (make-test-harness xor-gate-test))
    (tests gate-inputs xor-truth-table))
  (define-test-suite
    all-gate-tests
    (and-tests)
    (or-tests)
    (xor-tests))
  (run-tests all-gate-tests))

运行测试

racket@29761897.rkt> ,enter "/home/ben/StackOverflow/29761897.rkt"
12 success(es) 0 failure(s) 0 error(s) 12 test(s) run
0

由于所有测试都通过了,我们现在可以上交家庭作业[一如既往地受学术政策的约束]。

笔记

使用真值#f#t为Racket的测试工具提供了更清晰的钩子。它还允许直接编写谓词,而不是序列化和反序列化10

下面是一个简单的定义,其中真值表很清楚:

(define (and-gate a b)
  (cond
    [(and (= a 0) (= b 0))  0]
    [(and (= a 0) (= b 1))  0]
    [(and (= a 1) (= b 0))  0]
    [(and (= a 1) (= b 1))  1]))

如果我们注意到只有一个子句的结果是 1,而所有其他子句都给出 0,我们可以写:

(define (and-gate a b)
  (cond
    [(and (= a 1) (= b 1))  1]
    [else                   0]))

最新更新