(define (numerical-quantities-equal? x y) (if (and (number? x) (number? y)) (= x y) (eqv? x y))) (define (choose-numerical-quantity ns) (or (find-matching-item ns number?) (car ns))) ;;; Celsius-Farenheit conversion example (define network (cp:make-network 'network (cp:make-value-model numerical-quantity? numerical-quantities-equal? choose-numerical-quantity))) (define c (cp:make-connector 'c network)) (define f (cp:make-connector 'f network)) (define u (cp:make-connector 'u network)) (define v (cp:make-connector 'v network)) (define nine (cp:make-connector 'nine network)) (define five (cp:make-connector 'five network)) (define thirty-two (cp:make-connector 'thirty-two network)) (cp:assume-value nine 9) (cp:assume-value five 5) (cp:assume-value thirty-two 32) (cp:make-constraint cp:multiplier #f network u c nine) (cp:make-constraint cp:multiplier #f network u v five) (cp:make-constraint cp:adder #f network f v thirty-two) (cp:assume-value c 100) ;Unspecified return value (cp:has-value? f) ;Value: #t (cp:value-of f) ;Value: 212 (cp:retract-value c) ;Value: #t (cp:has-value? f) ;Value: #f (cp:assume-value c -40) ;Unspecified return value (cp:has-value? f) ;Value: #t (cp:value-of f) ;Value: -40 (cp:retract-value c) ;Value: #t (cp:assume-value f 32) ;Unspecified return value (cp:has-value? c) ;Value: #t (cp:value-of c) ;Value: 0 (cp:why? c) ;(n25 (c = 0) (multiplier n24 n23) (n21 n22 n23)) ;(n24 (u = 0) (multiplier n26) (n21 n22)) ;(n23 (nine = 9) (premise) (n23)) ;(n26 (v = 0) (multiplier n21 n22) (n21 n22)) ;(n21 (f = 32) (premise) (n21)) ;(n22 (thirty-two = 32) (premise) (n22)) ;Unspecified return value (cp:retract-value f) ;Value: #t (cp:assume-value f 98.6) ;Unspecified return value (cp:has-value? c) ;Value: #t (cp:value-of c) ;Value: 37. (cp:why? c) ;(n30 (c = 37.) (multiplier n29 n23) (n27 n22 n28 n23)) ;(n29 (u = 333.) (multiplier n31 n28) (n27 n22 n28)) ;(n23 (nine = 9) (premise) (n23)) ;(n31 (v = 66.6) (multiplier n27 n22) (n27 n22)) ;(n28 (five = 5) (premise) (n28)) ;(n27 (f = 98.6) (premise) (n27)) ;(n22 (thirty-two = 32) (premise) (n22)) ;Unspecified return value ;;; Simple Electrical Circuit : source and resistor (define ckt1 (cp:make-network 'ckt1 (cp:make-value-model numerical-quantity? numerical-quantities-equal? choose-numerical-quantity))) ;;; terminal potentials (define es1 (cp:make-connector 'es1 ckt1)) (define es2 (cp:make-connector 'es2 ckt1)) (define er1 (cp:make-connector 'er1 ckt1)) (define er2 (cp:make-connector 'er2 ckt1)) ;;; terminal currents (define is1 (cp:make-connector 'is1 ckt1)) (define is2 (cp:make-connector 'is2 ckt1)) (define ir1 (cp:make-connector 'ir1 ckt1)) (define ir2 (cp:make-connector 'ir2 ckt1)) ;;; branch voltages (define vs (cp:make-connector 'vs ckt1)) (define vr (cp:make-connector 'vr ckt1)) ;;; parameters (define vss (cp:make-connector 'vss ckt1)) (define r (cp:make-connector 'r ckt1)) ;;; utility (define zero-i (cp:make-connector 'zero-i ckt1)) (cp:assume-value zero-i 0) ;;; KVL ;;; Nodes (cp:make-constraint cp:B=A 'KVL-N ckt1 es1 er1) (cp:make-constraint cp:B=A 'KVL-N ckt1 es2 er2) ;;; Elements (cp:make-constraint cp:adder 'KVL-E ckt1 es1 vs es2) (cp:make-constraint cp:adder 'KVL-E ckt1 er1 vr er2) ;;; KCL ;;; Nodes (cp:make-constraint cp:adder 'KCL-N ckt1 zero-i is1 ir1) (cp:make-constraint cp:adder 'KCL-N ckt1 zero-i is2 ir2) ;;; Elements (cp:make-constraint cp:adder 'KCL-E ckt1 zero-i is1 is2) (cp:make-constraint cp:adder 'KCL-E ckt1 zero-i ir1 ir2) ;;; VIC ;;; Voltage-source (cp:make-constraint cp:B=A 'Voltage-source ckt1 vss vs) ;;; Resistor (cp:make-constraint cp:multiplier 'OHM ckt1 vr ir1 r) ;;; Specific situation (cp:assume-value vss 12) (cp:assume-value r 6) (cp:has-value? ir1) ;Value: #f ;;; Declare ground. (cp:assume-value es1 0) (cp:has-value? ir1) ;Value: #t (cp:value-of ir1) ;Value: 2 ;;; Correct! (cp:retract-value r) ;Value: #t (cp:assume-value is2 3) (cp:value-of r) ;Value: 4 ;;; Yup... ;;; Ground potential should be a CP hypothetical... ;;; Note: algebra works under scmutils. (cp:retract-value es1) ;Value: #t (cp:assume-value es1 'E) (cp:why? r) ;(n48 (r = 4) (OHM n46 n47) (n42 n43 n44 n45)) ;(n46 (vr = 12) (KVL-E n49 n50) (n42 n43)) ;(n47 (ir1 = 3) (KCL-N n44 n51) (n44 n45)) ;(n49 (er1 = E) (KVL-N n42) (n42)) ;(n50 (er2 = (+ -12 E)) (KVL-N n52) (n42 n43)) ;(n44 (zero-i = 0) (premise) (n44)) ;(n51 (is1 = -3) (KCL-E n44 n45) (n44 n45)) ;(n42 (es1 = E) (premise) (n42)) ;(n52 (es2 = (+ -12 E)) (KVL-E n42 n53) (n42 n43)) ;(n45 (is2 = 3) (premise) (n45)) ;(n53 (vs = 12) (Voltage-source n43) (n43)) ;(n43 (vss = 12) (premise) (n43)) ;Unspecified return value ;;; If an expression derived from a variable plunk premise ;;; does not contain the plunk variable, we may conclude ;;; that the assumption of the plunk variable is not ;;; an essential ingredient of that expression and edit the ;;; dependencies to eliminate the plunk premise. ;;; Now make a contradiction. (cp:retract-value es1) ;Value: #t (cp:has-value? r) ;Value: #f (cp:assume-value r 6) ;Unspecified return value (cp:assume-value es2 0) ;Warning: Contradiction: #[tms:node 54] (cp:explain-contradiction ckt1) ;(n54 contradiction (vss n57 n43) (n44 n45 n55 n43 n56)) ;(n57 (vss = 18) (Voltage-source n58) (n44 n45 n55 n56)) ;(n43 (vss = 12) (premise) (n43)) ;(n58 (vs = 18) (KVL-E n59 n56) (n44 n45 n55 n56)) ;(n59 (es1 = 18) (KVL-N n60) (n44 n45 n55 n56)) ;(n56 (es2 = 0) (premise) (n56)) ;(n60 (er1 = 18) (KVL-E n61 n62) (n44 n45 n55 n56)) ;(n61 (vr = 18) (OHM n47 n55) (n44 n45 n55)) ;(n62 (er2 = 0) (KVL-N n56) (n56)) ;(n47 (ir1 = 3) (KCL-N n44 n51) (n44 n45)) ;(n55 (r = 6) (premise) (n55)) ;(n44 (zero-i = 0) (premise) (n44)) ;(n51 (is1 = -3) (KCL-E n44 n45) (n44 n45)) ;(n45 (is2 = 3) (premise) (n45)) ;Unspecified return value ;;; Still under development: solve, handler, plunker. ;;; Simple Electrical Circuit : source and voltage divider (define algebra) (define ckt2 (let ((alg (algebraic-solver #f))) (set! algebra alg) (cp:make-network 'ckt2 (alg 'value-model)))) (define cp:plunk-connector (algebra 'plunk-connector)) ;;; terminal potentials (define esh (cp:make-connector 'esh ckt2)) (define esl (cp:make-connector 'esl ckt2)) (define er1h (cp:make-connector 'er1h ckt2)) (define er1l (cp:make-connector 'er1l ckt2)) (define er2h (cp:make-connector 'er2h ckt2)) (define er2l (cp:make-connector 'er2l ckt2)) ;;; terminal currents (define ish (cp:make-connector 'ish ckt2)) (define isl (cp:make-connector 'isl ckt2)) (define ir1h (cp:make-connector 'ir1h ckt2)) (define ir1l (cp:make-connector 'ir1l ckt2)) (define ir2h (cp:make-connector 'ir2h ckt2)) (define ir2l (cp:make-connector 'ir2l ckt2)) ;;; branch voltages (define vs (cp:make-connector 'vs ckt2)) (define vr1 (cp:make-connector 'vr1 ckt2)) (define vr2 (cp:make-connector 'vr2 ckt2)) ;;; parameters (define vss (cp:make-connector 'vss ckt2)) (define r1 (cp:make-connector 'r1 ckt2)) (define r2 (cp:make-connector 'r2 ckt2)) ;;; utility (define zero-i (cp:make-connector 'zero-i ckt2)) (cp:assume-value zero-i 0) ;;; KVL ;;; Nodes (cp:make-constraint cp:B=A 'KVL-N ckt2 esh er1h) (cp:make-constraint cp:B=A 'KVL-N ckt2 er1l er2h) (cp:make-constraint cp:B=A 'KVL-N ckt2 esl er2l) ;;; Elements (cp:make-constraint cp:adder 'KVL-E ckt2 esh vs esl) (cp:make-constraint cp:adder 'KVL-E ckt2 er1h vr1 er1l) (cp:make-constraint cp:adder 'KVL-E ckt2 er2h vr2 er2l) ;;; KCL ;;; Nodes (cp:make-constraint cp:adder 'KCL-N ckt2 zero-i ish ir1h) (cp:make-constraint cp:adder 'KCL-N ckt2 zero-i ir1l ir2h) (cp:make-constraint cp:adder 'KCL-N ckt2 zero-i isl ir2l) ;;; Elements (cp:make-constraint cp:adder 'KCL-E ckt2 zero-i ish isl) (cp:make-constraint cp:adder 'KCL-E ckt2 zero-i ir1h ir1l) (cp:make-constraint cp:adder 'KCL-E ckt2 zero-i ir2h ir2l) ;;; VIC ;;; Voltage-source (cp:make-constraint cp:B=A 'Voltage-source ckt2 vss vs) ;;; Resistor (cp:make-constraint cp:multiplier 'OHM ckt2 vr1 ir1h r1) (cp:make-constraint cp:multiplier 'OHM ckt2 vr2 ir1h r2) ;;; Specific situation (cp:assume-value vss 12) (cp:assume-value r1 9) (cp:assume-value r2 3) ;;; Declare ground. (cp:assume-value esl 0) (cp:has-value? er2h) ;Value: #f (cp:plunk-connector er2h) (pp-comment (algebra 'equations)) ;(((+ -12 (* 4 x-er2h)) (#[tms:node 28]) (x-er2h))) ;Unspecified return value (cp:value-of er2h) ;Value: 3 ;;; Correct! (for-each (lambda (conn) (pp-comment `(,(cp:connector-name conn) ,(cp:value-of conn)))) (cp:network-connectors ckt2)) ;(zero-i 0) ;(r2 3) ;(r1 9) ;(vss 12) ;(vr2 3) ;(vr1 9) ;(vs 12) ;(ir2l -1) ;(ir2h 1) ;(ir1l -1) ;(ir1h 1) ;(isl 1) ;(ish -1) ;(er2l 0) ;(er2h 3) ;(er1l 3) ;(er1h 12) ;(esl 0) ;(esh 12) ;Unspecified return value (cp:why? er2h) ;(n33 (er2h = 3) (equation-solver n28) (n29 n30 n31 n32)) ;(n28 (+ -12 (* 4 x-er2h)) (additional n35 n30) (n29 n30 n31 n32 n34)) ;(n35 (r1 = (+ -3 (/ 36 x-er2h))) (OHM n36 n37) (n31 n34 n32 n29)) ;(n30 (r1 = 9) (premise) (n30)) ;(n36 (vr1 = (+ 12 (* -1 x-er2h))) (KVL-E n38 n39) (n31 n32 n34)) ;(n37 (ir1h = (* 1/3 x-er2h)) (OHM n40 n29) (n34 n32 n29)) ;(n38 (er1h = 12) (KVL-N n41) (n31 n32)) ;(n39 (er1l = x-er2h) (KVL-N n34) (n34)) ;(n40 (vr2 = x-er2h) (KVL-E n34 n42) (n34 n32)) ;(n29 (r2 = 3) (premise) (n29)) ;(n41 (esh = 12) (KVL-E n43 n32) (n31 n32)) ;(n34 (er2h = x-er2h) (premise) (n34)) ;(n42 (er2l = 0) (KVL-N n32) (n32)) ;(n43 (vs = 12) (Voltage-source n31) (n31)) ;(n32 (esl = 0) (premise) (n32)) ;(n31 (vss = 12) (premise) (n31)) ;Unspecified return value