;; circuit2.clp: Jess code to represent a logic circuit ;; ;; Note: this is demonstration code only; ;; IT DOESN'T (COMPLETELY) WORK! ;; ;; Modified from circuit1.clp; the idea was to include additional ;; information so that changes would propagate through the network but, ;; once an update had occurred, CEs would stop matching on rule LHS ;; and thus infinite loops would be avoided. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Circuit structure ;; ;; Each circuit element has a name, connectivity information, a ;; current value, and an "iteration number" used to detect when a ;; source element has a value that is "more recent" than a destination ;; element . ;; a NOT gate (deftemplate not-gate "Logical not" (slot name) (slot input) (slot output) (slot value (default unknown)) (slot iteration (default 0))) ;; Input port (deftemplate input-port "Circuit input" (slot name) (slot output) (slot value (default unknown)) (slot iteration (default 0))) ;; Output port (deftemplate output-port "Circuit output" (slot name) (slot input) (slot value (default unknown)) (slot iteration (default 0))) ;; Connector (deftemplate connector "Connects one input to one or more outputs" (slot name) (slot input) (multislot output) (slot value (default unknown)) (slot iteration (default 0))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; A simple circuit (deffacts simple "A simple circuit" (input-port (name in1) (output conn1) (value TRUE) (iteration 1)) (connector (name conn1) (input in1) (output not1)) (not-gate (name not1) (input conn1) (output conn2)) (connector (name conn2) (input not1) (output out1)) (output-port (name out1) (input conn2))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Gate rules ;; Note that these rules DO work, but only for purely combinatorial ;; logic. Logic circuits with feedback (and thus internal state) don't ;; work, because once all of the iteration values have updated, the ;; rules stop firing, regardless of whether or not there are changed ;; element outputs that still need to be fed back to other elements' ;; inputs. (defrule propagate-input "Copy value from input port to connector" (input-port (name ?n) (output ?c) (value ?v&~unknown) (iteration ?it)) ?cf <- (connector (name ?c) (iteration ?cit&:(< ?cit ?it))) => (modify ?cf (value ?v) (iteration ?it))) (defrule compute-not "Compute output of a NOT gate" ?ngf <- (not-gate (name ?n) (input ?c) (iteration ?it)) (connector (name ?c) (value ?v&~unknown) (iteration ?cit&:(> ?cit ?it))) => (modify ?ngf (value (not ?v)) (iteration ?cit))) (defrule propagate-not "Propagate NOT gate output to connector" (not-gate (name ?n) (output ?c) (value ?v&~unknown) (iteration ?it)) ?cf <- (connector (name ?c) (iteration ?cit&:(< ?cit ?it))) => (modify ?cf (value ?v) (iteration ?it))) (defrule propagate-output "Copy value from connector to output port" ?of <- (output-port (name ?n) (input ?c) (iteration ?it)) (connector (name ?c) (value ?v&~unknown) (iteration ?cit&:(> ?cit ?it))) => (modify ?of (value ?v) (iteration ?cit)))