Object subclass: #Adder instanceVariableNames: 'a1 a2 sum ' classVariableNames: '' poolDictionaries: '' category: 'SICP3.3.5-Propagation of Constraints'! !Adder methodsFor: 'private' stamp: 'sumim 6/17/2003 17:52'! setA1: newA1 a2: newA2 sum: newSum a1 _ newA1. a2 _ newA2. sum _ newSum. a1 connect: self. a2 connect: self. sum connect: self ! ! !Adder methodsFor: 'updating' stamp: 'sumim 6/17/2003 17:57'! processForgetValue a1 forgetValue: self. a2 forgetValue: self. sum forgetValue: self. self processNewValue! ! !Adder methodsFor: 'updating' stamp: 'sumim 6/17/2003 18:07'! processNewValue (a1 hasValue and: [ a2 hasValue ]) ifTrue: [ sum value: a1 value + a2 value setter: self ] ifFalse: [ (a1 hasValue and: [ sum hasValue ]) ifTrue: [ a2 value: sum value - a1 value setter: self ] ifFalse: [ (a2 hasValue and: [ sum hasValue ]) ifTrue: [ a1 value: sum value - a2 value setter: self ]]]! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! Adder class instanceVariableNames: ''! !Adder class methodsFor: 'instance creation' stamp: 'sumim 6/17/2003 18:23'! a1: a1 a2: a2 sum: sum ^ self new setA1: a1 a2: a2 sum: sum; yourself! ! Object subclass: #CelsiusFahrenheitConverter instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'SICP3.3.5-Propagation of Constraints'! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! CelsiusFahrenheitConverter class instanceVariableNames: ''! !CelsiusFahrenheitConverter class methodsFor: 'example' stamp: 'sumim 6/17/2003 18:32'! celsius: celsius fahrenheit: fahrenheit | u v w x y | u _ Connector new. v _ Connector new. w _ Connector new. x _ Connector new. y _ Connector new. Multiplier m1: celsius m2: w product: u. Multiplier m1: v m2: x product: u. Adder a1: v a2: y sum: fahrenheit. Constant value: 9 connector: w. Constant value: 5 connector: x. Constant value: 32 connector: y ! ! !CelsiusFahrenheitConverter class methodsFor: 'example' stamp: 'sumim 6/18/2003 00:29'! example1 "self example1" | c f | Transcript clear. c _ Connector new. f _ Connector new. CelsiusFahrenheitConverter celsius: c fahrenheit: f. Probe name: 'Celsius temp' connector: c. Probe name: 'Fahrenheit temp' connector: f. c value: 25 setter: #user! ! !CelsiusFahrenheitConverter class methodsFor: 'example' stamp: 'sumim 6/18/2003 00:29'! example2 "self example2" | c f | Transcript clear. c _ Connector new. f _ Connector new. CelsiusFahrenheitConverter celsius: c fahrenheit: f. Probe name: 'Celsius temp' connector: c. Probe name: 'Fahrenheit temp' connector: f. c value: 25 setter: #user. f value: 212 setter: #user! ! !CelsiusFahrenheitConverter class methodsFor: 'example' stamp: 'sumim 6/18/2003 00:29'! example3 "self example3" | c f | Transcript clear. c _ Connector new. f _ Connector new. CelsiusFahrenheitConverter celsius: c fahrenheit: f. Probe name: 'Celsius temp' connector: c. Probe name: 'Fahrenheit temp' connector: f. c value: 25 setter: #user. f value: 212 setter: #user. c forgetValue: #user. f value: 212 setter: #user! ! Object subclass: #Connector instanceVariableNames: 'value informant constraints ' classVariableNames: '' poolDictionaries: '' category: 'SICP3.3.5-Propagation of Constraints'! !Connector methodsFor: 'connecting' stamp: 'sumim 6/17/2003 18:05'! connect: newConstraint (constraints includes: newConstraint) ifFalse: [ constraints add: newConstraint ]. self hasValue ifTrue: [ newConstraint processNewValue ]! ! !Connector methodsFor: 'accessing' stamp: 'sumim 6/17/2003 18:42'! forgetValue: retractor retractor == informant ifTrue: [ informant _ nil. constraints do: [ :constraint | constraint ~~ retractor ifTrue: [ constraint processForgetValue]]]! ! !Connector methodsFor: 'accessing' stamp: 'sumim 6/17/2003 17:38'! value ^ value! ! !Connector methodsFor: 'accessing' stamp: 'sumim 6/18/2003 00:27'! value: newValue setter: setter self hasValue not ifTrue: [ value _ newValue. informant _ setter. constraints do: [ :constraint | constraint == setter ifFalse: [ constraint processNewValue ]]] ifFalse: [ newValue ~~ value ifTrue: [ self notify: 'Contradiction: ', value printString, ' ', newValue printString]]! ! !Connector methodsFor: 'testing' stamp: 'sumim 6/17/2003 18:37'! hasValue ^ informant notNil! ! !Connector methodsFor: 'initialization' stamp: 'sumim 6/17/2003 17:50'! initialize constraints _ OrderedCollection new! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! Connector class instanceVariableNames: ''! !Connector class methodsFor: 'instance creation' stamp: 'sumim 6/17/2003 18:28'! new ^ super new initialize; yourself! ! Object subclass: #Constant instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'SICP3.3.5-Propagation of Constraints'! !Constant methodsFor: 'private' stamp: 'sumim 6/17/2003 18:38'! setValue: newValue connector: connector connector connect: self. connector value: newValue setter: self! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! Constant class instanceVariableNames: ''! !Constant class methodsFor: 'instance creation' stamp: 'sumim 6/17/2003 18:23'! value: value connector: connector ^ self new setValue: value connector: connector; yourself! ! Object subclass: #Multiplier instanceVariableNames: 'm1 m2 product ' classVariableNames: '' poolDictionaries: '' category: 'SICP3.3.5-Propagation of Constraints'! !Multiplier methodsFor: 'updating' stamp: 'sumim 6/17/2003 18:09'! processForgetValue m1 forgetValue: self. m2 forgetValue: self. product forgetValue: self. self processNewValue! ! !Multiplier methodsFor: 'updating' stamp: 'sumim 6/17/2003 18:07'! processNewValue (m1 value == 0 or: [ m2 value == 0 ]) ifTrue: [ product value: 0 setter: self ] ifFalse: [ (m1 hasValue and: [ m2 hasValue ]) ifTrue: [ product value: m1 value * m2 value setter: self ] ifFalse: [ (m1 hasValue and: [ product hasValue ]) ifTrue: [ m2 value: product value / m1 value setter: self ] ifFalse: [ (m2 hasValue and: [ product hasValue ]) ifTrue: [ m1 value: product value / m2 value setter: self ]]]]! ! !Multiplier methodsFor: 'private' stamp: 'sumim 6/17/2003 17:59'! setM1: newM1 m2: newM2 product: newProduct m1 _ newM1. m2 _ newM2. product _ newProduct. m1 connect: self. m2 connect: self. product connect: self! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! Multiplier class instanceVariableNames: ''! !Multiplier class methodsFor: 'instance creation' stamp: 'sumim 6/17/2003 18:23'! m1: m1 m2: m2 product: product ^ self new setM1: m1 m2: m2 product: product; yourself! ! Object subclass: #Probe instanceVariableNames: 'name connector ' classVariableNames: '' poolDictionaries: '' category: 'SICP3.3.5-Propagation of Constraints'! !Probe methodsFor: 'printing' stamp: 'sumim 6/17/2003 18:17'! printProbe: value World findATranscript: nil. Transcript cr; show: 'Probe: ', name printString, ' = ', value printString! ! !Probe methodsFor: 'updating' stamp: 'sumim 6/17/2003 18:18'! processForgetValue self printProbe: '?'! ! !Probe methodsFor: 'updating' stamp: 'sumim 6/17/2003 18:18'! processNewValue self printProbe: connector value! ! !Probe methodsFor: 'private' stamp: 'sumim 6/17/2003 18:14'! setName: newName connector: newConnector name _ newName. connector _ newConnector. connector connect: self! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! Probe class instanceVariableNames: ''! !Probe class methodsFor: 'instance creation' stamp: 'sumim 6/17/2003 18:23'! name: probeName connector: connector ^ self new setName: probeName connector: connector; yourself! !