object solver extends Application { trait Constraint { def newValue: unit; def dropValue: unit } object NoConstraint extends Constraint { def newValue: unit = error("NoConstraint.newValue"); def dropValue: unit = error("NoConstraint.dropValue"); } case class Adder(a1: Quantity, a2: Quantity, sum: Quantity) extends Constraint { def newValue: unit = Triple(a1.getValue, a2.getValue, sum.getValue) match { case Triple(Some(x1), Some(x2), _ ) => sum.setValue(x1 + x2, this) case Triple(Some(x1), _ , Some(r)) => a2.setValue(r - x1, this) case Triple(_ , Some(x2), Some(r)) => a1.setValue(r - x2, this) case _ => () } def dropValue: unit = { a1.forgetValue(this); a2.forgetValue(this); sum.forgetValue(this); } a1 connect this; a2 connect this; sum connect this; } case class Constant(q: Quantity, v: double) extends Constraint { def newValue: unit = error("Constant.newValue"); def dropValue: unit = error("Constant.dropValue"); q connect this; q.setValue(v, this); } case class Probe(name: String, q: Quantity) extends Constraint { def newValue: unit = printProbe(q.getValue); def dropValue: unit = printProbe(None); private def printProbe(v: Option[double]): unit = { val vstr = v match { case Some(x) => x.toString() case None => "?" } Console.println("Probe: " + name + " = " + vstr); } q connect this } // COMPLETE HERE: define constraints for multiplication, equality and square. class Quantity { private var value: Option[double] = None; private var constraints: List[Constraint] = List(); private var informant: Constraint = null; def getValue: Option[double] = value; def setValue(v: double, setter: Constraint): unit = value match { case Some(v1) => if (v != v1) error("Error! contradiction: " + v + " and " + v1); case None => { informant = setter; value = Some(v); for (val c <- constraints; c != informant) c.newValue; } } def setValue(v: double): unit = setValue(v, NoConstraint); def forgetValue(retractor: Constraint): unit = { if (retractor == informant) { value = None; for (val c <- constraints; c != informant) c.dropValue; } } def forgetValue: unit = forgetValue(NoConstraint); def connect(c: Constraint): unit = { constraints = c :: constraints; value match { case Some(_) => c.newValue case None => () } } def +(that: Quantity): Quantity = { val sum = new Quantity; Adder(this, that, sum); sum } // COMPLETE HERE: define operators "*" and "===". override def toString(): String = value match { case None => " ?" case Some(v) => v.toString() } } // COMPLETE HERE: define a function "c" that creates a constant quantity. def adderExample = { val q1, q2, q3 = new Quantity; Adder(q1, q2, q3); Probe("q1", q1); Probe("q2", q2); Probe("q3", q3); q1.setValue(20); q2.setValue(22); q1.forgetValue; q2.forgetValue; Console.println("-----"); q1.setValue(20); q3.setValue(22); q1.forgetValue; q3.forgetValue; Console.println("-----"); q2.setValue(20); q3.setValue(22); q2.forgetValue; q3.forgetValue; Console.println("-----"); } def converterExample = { // COMPLETE HERE: write the Celsius/Fahrenheit converter. } adderExample; converterExample; }

AltStyle によって変換されたページ (->オリジナル) /