# GATE probing networks of unless gates
[hear] (define set-input /
         ? circuit /
         ? index /
         ? value /
         assign wire (list-ref (circuit) (index))
         (map (? w (if (equal (w) (wire))
               (vector (list-ref (w) 0)
                   (list-ref (w) 1)
                   (list-ref (w) 2)
                   (list-ref (w) 3)
                   (value))
               (w)))
              (circuit)));

[hear] (define read-output /
         ? circuit /
         ? index /
         assign len (list-length / circuit) /
         assign wire (list-ref (circuit) / - (- (len) 1) (index)) /
         list-ref (wire) 4);

[hear] (define sim /
         ? circuit / ? steps / ? setter
         (if (> (steps) 0)
             (sim (simulate-unless (setter / circuit)) (- (steps) 1) (setter))
             (circuit)));

[hear] (define smart-sim /
         ? circuit /
         ? setter /
         sim (circuit) (list-length / circuit) (setter));

       # test cos_not gate
[hear] (define cos_not_harness /
         ? x /
         assign c (cos_not_gate) /
         assign c (smart-sim (c) (? c (set-input (c) 0 (x)))) /
         read-output (c) 0);

[hear] (= (false) / cos_not_harness / true);

[hear] (= (true) / cos_not_harness / false);

       # test cos_and gate
[hear] (define cos_and_harness /
         ? x / ? y /
         assign c (cos_and_gate) /
         assign c (smart-sim (c) (? c (set-input (set-input (c) 0 (x)) 1 (y)))) /
         read-output (c) 0);

[hear] (= (false) / cos_and_harness (false) (false));

[hear] (= (false) / cos_and_harness (false) (true));

[hear] (= (false) / cos_and_harness (true) (false));

[hear] (= (true) / cos_and_harness (true) (true));

       # this code is more awkward than it needs to be -
       # should make circuits mutable