From 0246e3cddbfde4b3376c4d273e98911a8f9896e0 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <ekneuss@gmail.com> Date: Tue, 20 Nov 2012 03:26:02 +0100 Subject: [PATCH] Type this shit --- src/main/scala/leon/aographs/Graph.scala | 119 +++++++++++------------ 1 file changed, 58 insertions(+), 61 deletions(-) diff --git a/src/main/scala/leon/aographs/Graph.scala b/src/main/scala/leon/aographs/Graph.scala index 3e325def9..9f986e67e 100644 --- a/src/main/scala/leon/aographs/Graph.scala +++ b/src/main/scala/leon/aographs/Graph.scala @@ -15,58 +15,61 @@ object AOCost { } trait AOTask[S <: AOSolution] { - def composeSolution(sols: List[S]): S def cost: AOCost } +trait AOAndTask[S <: AOSolution] extends AOTask[S] { + def composeSolution(sols: List[S]): S +} + +trait AOOrTask[S <: AOSolution] extends AOTask[S] { +} + trait AOSolution { def cost: AOCost } - -class AndOrGraph[T <: AOTask[S], S <: AOSolution](val root: T) { +class AndOrGraph[AT <: AOAndTask[S], OT <: AOOrTask[S], S <: AOSolution](val root: OT) { type C = AOCost var tree: Tree = RootNode trait Tree { - val task : T - val parent: Node + val task : AOTask[S] + val parent: Node[_] def minCost: C def isSolved: Boolean - def isUnsolvable: Boolean } - abstract class AndTree extends Tree - abstract class OrTree extends Tree + abstract class AndTree extends Tree { + override val task: AT + } + abstract class OrTree extends Tree { + override val task: OT + } - trait Leaf extends Tree with Ordered[Leaf] { - val minCost: C = task.cost - def compare(that: Leaf) = this.minCost.compare(that.minCost) + trait Leaf extends Tree { + val minCost: C = task.cost def isSolved: Boolean = false - def isUnsolvable: Boolean = false - def expandWith(succ: List[T]) } - trait Node { - def expandLeaf(l: Leaf, succ: List[T]) - def unsolvable(l: Tree) - def notifySolution(sub: Tree, sol: S) + trait Node[T <: Tree] extends Tree { + def unsolvable(l: T) + def notifySolution(sub: T, sol: S) var solution: Option[S] = None - var isUnsolvable = false def isSolved: Boolean = solution.isDefined } - case class AndNode(parent: OrNode, subTasks: List[T], task: T) extends AndTree with Node { - var subProblems = Map[T, OrTree]() - var subSolutions = Map[T, S]() + case class AndNode(parent: OrNode, subTasks: List[OT], task: AT) extends AndTree with Node[OrTree] { + var subProblems = Map[OT, OrTree]() + var subSolutions = Map[OT, S]() def computeCost = { solution match { @@ -81,12 +84,11 @@ class AndOrGraph[T <: AOTask[S], S <: AOSolution](val root: T) { var minCost = computeCost - def unsolvable(l: Tree) { - isUnsolvable = true + def unsolvable(l: OrTree) { parent.unsolvable(this) } - def expandLeaf(l: Leaf, succ: List[T]) { + def expandLeaf(l: OrLeaf, succ: List[AT]) { val n = OrNode(this, Map(), l.task) n.alternatives = succ.map(t => t -> AndLeaf(n, t)).toMap n.minAlternative = n.computeMin @@ -94,7 +96,7 @@ class AndOrGraph[T <: AOTask[S], S <: AOSolution](val root: T) { subProblems += l.task -> n } - def notifySolution(sub: Tree, sol: S) { + def notifySolution(sub: OrTree, sol: S) { subSolutions += sub.task -> sol if (subSolutions.size == subProblems.size) { @@ -114,35 +116,18 @@ class AndOrGraph[T <: AOTask[S], S <: AOSolution](val root: T) { } object RootNode extends OrLeaf(null, root) { - override def expandWith(succ: List[T]) { - val n = new OrNode(null, Map(), task) { - override def unsolvable(l: Tree) { - alternatives -= l.task - - if (alternatives.isEmpty) { - isUnsolvable = true - } else { - minAlternative = computeMin - } - } - } - n.alternatives = succ.map(t => t -> AndLeaf(n, t)).toMap - n.minAlternative = n.computeMin - - tree = n - } } - case class AndLeaf(parent: OrNode, task: T) extends AndTree with Leaf { - def expandWith(succ: List[T]) { + case class AndLeaf(parent: OrNode, task: AT) extends AndTree with Leaf { + def expandWith(succ: List[OT]) { parent.expandLeaf(this, succ) } } - case class OrNode(parent: AndNode, var alternatives: Map[T, AndTree], task: T) extends OrTree with Node { + case class OrNode(parent: AndNode, var alternatives: Map[AT, AndTree], task: OT) extends OrTree with Node[AndTree] { var minAlternative: Tree = _ def minCost: C = minAlternative.minCost @@ -154,18 +139,17 @@ class AndOrGraph[T <: AOTask[S], S <: AOSolution](val root: T) { } } - def unsolvable(l: Tree) { + def unsolvable(l: AndTree) { alternatives -= l.task if (alternatives.isEmpty) { - isUnsolvable = true parent.unsolvable(this) } else { minAlternative = computeMin } } - def expandLeaf(l: Leaf, succ: List[T]) { + def expandLeaf(l: AndLeaf, succ: List[OT]) { val n = AndNode(this, succ, l.task) n.subProblems = succ.map(t => t -> OrLeaf(n, t)).toMap n.minCost = n.computeCost @@ -173,7 +157,7 @@ class AndOrGraph[T <: AOTask[S], S <: AOSolution](val root: T) { alternatives += l.task -> n } - def notifySolution(sub: Tree, sol: S) { + def notifySolution(sub: AndTree, sol: S) { solution match { case Some(preSol) if (preSol.cost < sol.cost) => solution = Some(sol) @@ -189,14 +173,14 @@ class AndOrGraph[T <: AOTask[S], S <: AOSolution](val root: T) { } } - case class OrLeaf(parent: AndNode, task: T) extends OrTree with Leaf { - def expandWith(succ: List[T]) { + case class OrLeaf(parent: AndNode, task: OT) extends OrTree with Leaf { + def expandWith(succ: List[AT]) { parent.expandLeaf(this, succ) } } } -abstract class AndOrGraphSearch[T <: AOTask[S], S <: AOSolution](val g: AndOrGraph[T, S]) { +abstract class AndOrGraphSearch[AT <: AOAndTask[S], OT <: AOOrTask[S], S <: AOSolution](val g: AndOrGraph[AT, OT, S]) { import collection.mutable.PriorityQueue def nextLeaf: Option[g.Leaf] = { @@ -220,23 +204,36 @@ abstract class AndOrGraphSearch[T <: AOTask[S], S <: AOSolution](val g: AndOrGra } abstract class ExpandResult - case class Expanded(sub: List[T]) extends ExpandResult + case class ExpandedAnd(sub: List[OT]) extends ExpandResult + case class ExpandedOr(sub: List[AT]) extends ExpandResult case class ExpandSuccess(sol: S) extends ExpandResult case object ExpandFailure extends ExpandResult var continue = true def search = { - while (!g.tree.isSolved && continue && !g.tree.isUnsolvable) { + while (!g.tree.isSolved && continue) { nextLeaf match { case Some(l) => - processLeaf(l) match { - case r @ Expanded(ls) => - l.expandWith(ls) - case r @ ExpandSuccess(sol) => - l.parent.notifySolution(l, sol) - case r @ ExpandFailure => - l.parent.unsolvable(l) + l match { + case al: g.AndLeaf => + processLeaf(al) match { + case ExpandedAnd(ls) => + al.expandWith(ls) + case r @ ExpandSuccess(sol) => + al.parent.notifySolution(al, sol) + case _ => + al.parent.unsolvable(al) + } + case ol: g.OrLeaf => + processLeaf(ol) match { + case ExpandedOr(ls) => + ol.expandWith(ls) + case r @ ExpandSuccess(sol) => + ol.parent.notifySolution(ol, sol) + case _ => + ol.parent.unsolvable(ol) + } } case None => continue = false -- GitLab