From 9a05ae052faa79d2085c3a8f458b6063493bc8d0 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <ekneuss@gmail.com> Date: Mon, 19 Nov 2012 14:19:40 +0100 Subject: [PATCH] Make RuleInapplicable a RuleAlternatives with no alternative --- src/main/scala/leon/synthesis/Rules.scala | 7 +++++-- src/main/scala/leon/synthesis/Task.scala | 8 +++++--- .../leon/synthesis/heuristics/ADTInduction.scala | 4 ++-- .../leon/synthesis/heuristics/IntInduction.scala | 2 +- .../synthesis/heuristics/OptimisticInjection.scala | 2 +- .../synthesis/heuristics/SelectiveInlining.scala | 2 +- src/main/scala/leon/synthesis/rules/ADTDual.scala | 2 +- src/main/scala/leon/synthesis/rules/ADTSplit.scala | 14 ++++++++------ src/main/scala/leon/synthesis/rules/Assert.scala | 4 ++-- .../scala/leon/synthesis/rules/CaseSplit.scala | 4 ++-- src/main/scala/leon/synthesis/rules/Cegis.scala | 2 +- .../scala/leon/synthesis/rules/EqualitySplit.scala | 14 ++++++++------ src/main/scala/leon/synthesis/rules/Ground.scala | 4 ++-- .../leon/synthesis/rules/IntegerEquation.scala | 2 +- .../leon/synthesis/rules/IntegerInequalities.scala | 2 +- src/main/scala/leon/synthesis/rules/OnePoint.scala | 2 +- .../leon/synthesis/rules/OptimisticGround.scala | 10 +++++----- .../leon/synthesis/rules/UnconstrainedOutput.scala | 2 +- .../scala/leon/synthesis/rules/Unification.scala | 4 ++-- .../scala/leon/synthesis/rules/UnusedInput.scala | 2 +- 20 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/main/scala/leon/synthesis/Rules.scala b/src/main/scala/leon/synthesis/Rules.scala index f6b957d1d..ea4271b45 100644 --- a/src/main/scala/leon/synthesis/Rules.scala +++ b/src/main/scala/leon/synthesis/Rules.scala @@ -27,14 +27,17 @@ object Rules { } sealed abstract class RuleResult -case object RuleInapplicable extends RuleResult case class RuleSuccess(solution: Solution) extends RuleResult -case class RuleAlternatives(steps: Set[RuleMultiSteps]) extends RuleResult +case class RuleAlternatives(steps: Traversable[RuleMultiSteps]) extends RuleResult case class RuleMultiSteps(subProblems: List[Problem], interSteps: List[List[Solution] => List[Problem]], onSuccess: List[Solution] => (Solution, Boolean)) +object RuleInapplicable { + def apply() = RuleAlternatives(Seq()) +} + object RuleStep { def apply(subProblems: List[Problem], onSuccess: List[Solution] => Solution) = { RuleMultiSteps(subProblems, Nil, onSuccess.andThen((_, true))) diff --git a/src/main/scala/leon/synthesis/Task.scala b/src/main/scala/leon/synthesis/Task.scala index 2e565bbad..260745880 100644 --- a/src/main/scala/leon/synthesis/Task.scala +++ b/src/main/scala/leon/synthesis/Task.scala @@ -27,7 +27,7 @@ class Task(synth: Synthesizer, var solution: Option[Solution] = None var solver: Option[RuleApplication] = None - var alternatives = Set[RuleApplication]() + var alternatives = Traversable[RuleApplication]() var minComplexity: AbsSolComplexity = new FixedSolComplexity(0) @@ -109,12 +109,14 @@ class Task(synth: Synthesizer, Nil + case RuleAlternatives(xs) if xs.isEmpty => + // Inapplicable + Nil + case RuleAlternatives(steps) => this.alternatives = steps.map( step => new RuleApplication(step.subProblems, step.interSteps, step.onSuccess) ) this.alternatives.flatMap(_.initProblems).toList - case RuleInapplicable => - Nil } } diff --git a/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala b/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala index 064163d0b..90b4ebd22 100644 --- a/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala +++ b/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala @@ -100,10 +100,10 @@ class ADTInduction(synth: Synthesizer) extends Rule("ADT Induction", synth, 80) HeuristicOneStep(synth, p, subProblemsInfo.map(_._1).toList, onSuccess) } else { - RuleInapplicable + RuleInapplicable() } } else { - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/heuristics/IntInduction.scala b/src/main/scala/leon/synthesis/heuristics/IntInduction.scala index c1000f824..a82eae8f7 100644 --- a/src/main/scala/leon/synthesis/heuristics/IntInduction.scala +++ b/src/main/scala/leon/synthesis/heuristics/IntInduction.scala @@ -58,7 +58,7 @@ class IntInduction(synth: Synthesizer) extends Rule("Int Induction", synth, 50) HeuristicOneStep(synth, p, List(subBase, subGT, subLT), onSuccess) case _ => - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala b/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala index cb6682fcc..8f3e65195 100644 --- a/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala +++ b/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala @@ -40,7 +40,7 @@ class OptimisticInjection(synth: Synthesizer) extends Rule("Opt. Injection", syn HeuristicOneStep(synth, p, List(sub), forward) } else { - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala b/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala index 60c066e5f..6ee4935f5 100644 --- a/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala +++ b/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala @@ -40,7 +40,7 @@ class SelectiveInlining(synth: Synthesizer) extends Rule("Sel. Inlining", synth, HeuristicOneStep(synth, p, List(sub), forward) } else { - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/rules/ADTDual.scala b/src/main/scala/leon/synthesis/rules/ADTDual.scala index 37d6cf63f..1cf0a71f1 100644 --- a/src/main/scala/leon/synthesis/rules/ADTDual.scala +++ b/src/main/scala/leon/synthesis/rules/ADTDual.scala @@ -28,7 +28,7 @@ class ADTDual(synth: Synthesizer) extends Rule("ADTDual", synth, 200) { RuleOneStep(List(sub), forward) } else { - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/rules/ADTSplit.scala b/src/main/scala/leon/synthesis/rules/ADTSplit.scala index 6d43a4a52..41236da02 100644 --- a/src/main/scala/leon/synthesis/rules/ADTSplit.scala +++ b/src/main/scala/leon/synthesis/rules/ADTSplit.scala @@ -13,7 +13,7 @@ class ADTSplit(synth: Synthesizer) extends Rule("ADT Split.", synth, 70) { def applyOn(task: Task): RuleResult = { val p = task.problem - val candidate = p.as.collect { + val candidates = p.as.collect { case IsTyped(id, AbstractClassType(cd)) => val optCases = for (dcd <- cd.knownDescendents) yield dcd match { @@ -44,8 +44,8 @@ class ADTSplit(synth: Synthesizer) extends Rule("ADT Split.", synth, 70) { } - candidate.find(_.isDefined) match { - case Some(Some((id, cases))) => + val steps = candidates.collect{ _ match { + case Some((id, cases)) => val oas = p.as.filter(_ != id) val subInfo = for(ccd <- cases) yield { @@ -72,9 +72,11 @@ class ADTSplit(synth: Synthesizer) extends Rule("ADT Split.", synth, 70) { Solution(Or(globalPre), sols.flatMap(_.defs).toSet, MatchExpr(Variable(id), cases)) } - RuleOneStep(subInfo.map(_._2).toList, onSuccess) + Some(RuleStep(subInfo.map(_._2).toList, onSuccess)) case _ => - RuleInapplicable - } + None + }}.flatten + + RuleAlternatives(steps) } } diff --git a/src/main/scala/leon/synthesis/rules/Assert.scala b/src/main/scala/leon/synthesis/rules/Assert.scala index 814632bce..29514b2b3 100644 --- a/src/main/scala/leon/synthesis/rules/Assert.scala +++ b/src/main/scala/leon/synthesis/rules/Assert.scala @@ -25,10 +25,10 @@ class Assert(synth: Synthesizer) extends Rule("Assert", synth, 200) { RuleOneStep(List(sub), forward) } } else { - RuleInapplicable + RuleInapplicable() } case _ => - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/rules/CaseSplit.scala b/src/main/scala/leon/synthesis/rules/CaseSplit.scala index dcd7e6835..42d7e5095 100644 --- a/src/main/scala/leon/synthesis/rules/CaseSplit.scala +++ b/src/main/scala/leon/synthesis/rules/CaseSplit.scala @@ -10,7 +10,7 @@ class CaseSplit(synth: Synthesizer) extends Rule("Case-Split", synth, 200) { def applyOn(task: Task): RuleResult = { val p = task.problem p.phi match { - case Or(Seq(o1, o2)) => + case Or(o1 :: o2 :: _) => val sub1 = Problem(p.as, p.c, o1, p.xs) val sub2 = Problem(p.as, p.c, o2, p.xs) @@ -21,7 +21,7 @@ class CaseSplit(synth: Synthesizer) extends Rule("Case-Split", synth, 200) { RuleOneStep(List(sub1, sub2), onSuccess) case _ => - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/rules/Cegis.scala b/src/main/scala/leon/synthesis/rules/Cegis.scala index 307840d69..14bf62a17 100644 --- a/src/main/scala/leon/synthesis/rules/Cegis.scala +++ b/src/main/scala/leon/synthesis/rules/Cegis.scala @@ -213,6 +213,6 @@ class CEGIS(synth: Synthesizer) extends Rule("CEGIS", synth, 150) { unrolings += 1 } while(unrolings < maxUnrolings && lastF != currentF && result.isEmpty && synth.continue) - result.getOrElse(RuleInapplicable) + result.getOrElse(RuleInapplicable()) } } diff --git a/src/main/scala/leon/synthesis/rules/EqualitySplit.scala b/src/main/scala/leon/synthesis/rules/EqualitySplit.scala index fe0214362..8cd63ef80 100644 --- a/src/main/scala/leon/synthesis/rules/EqualitySplit.scala +++ b/src/main/scala/leon/synthesis/rules/EqualitySplit.scala @@ -12,7 +12,7 @@ class EqualitySplit(synth: Synthesizer) extends Rule("Eq. Split.", synth, 90) { def applyOn(task: Task): RuleResult = { val p = task.problem - val candidate = p.as.groupBy(_.getType).map(_._2.toList).find { + val candidates = p.as.groupBy(_.getType).map(_._2.toList).filter { case List(a1, a2) => val toValEQ = Implies(p.c, Equals(Variable(a1), Variable(a2))) @@ -37,8 +37,8 @@ class EqualitySplit(synth: Synthesizer) extends Rule("Eq. Split.", synth, 90) { } - candidate match { - case Some(List(a1, a2)) => + val steps = candidates.map(_ match { + case List(a1, a2) => val sub1 = p.copy(c = And(Equals(Variable(a1), Variable(a2)), p.c)) val sub2 = p.copy(c = And(Not(Equals(Variable(a1), Variable(a2))), p.c)) @@ -50,9 +50,11 @@ class EqualitySplit(synth: Synthesizer) extends Rule("Eq. Split.", synth, 90) { Solution.none } - RuleOneStep(List(sub1, sub2), onSuccess) + Some(RuleStep(List(sub1, sub2), onSuccess)) case _ => - RuleInapplicable - } + None + }).flatten + + RuleAlternatives(steps) } } diff --git a/src/main/scala/leon/synthesis/rules/Ground.scala b/src/main/scala/leon/synthesis/rules/Ground.scala index 122829442..ddb4c7b6d 100644 --- a/src/main/scala/leon/synthesis/rules/Ground.scala +++ b/src/main/scala/leon/synthesis/rules/Ground.scala @@ -21,10 +21,10 @@ class Ground(synth: Synthesizer) extends Rule("Ground", synth, 500) { case (Some(false), model) => RuleSuccess(Solution(BooleanLiteral(false), Set(), Error(p.phi+" is UNSAT!").setType(tpe))) case _ => - RuleInapplicable + RuleInapplicable() } } else { - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/rules/IntegerEquation.scala b/src/main/scala/leon/synthesis/rules/IntegerEquation.scala index bb2005f9d..a8af1d203 100644 --- a/src/main/scala/leon/synthesis/rules/IntegerEquation.scala +++ b/src/main/scala/leon/synthesis/rules/IntegerEquation.scala @@ -43,7 +43,7 @@ class IntegerEquation(synth: Synthesizer) extends Rule("Integer Equation", synth allOthers = allOthers ++ candidates optionNormalizedEq match { - case None => RuleInapplicable + case None => RuleInapplicable() case Some(normalizedEq0) => { val eqas = problem.as.toSet.intersect(vars) diff --git a/src/main/scala/leon/synthesis/rules/IntegerInequalities.scala b/src/main/scala/leon/synthesis/rules/IntegerInequalities.scala index 760891e0c..80b340595 100644 --- a/src/main/scala/leon/synthesis/rules/IntegerInequalities.scala +++ b/src/main/scala/leon/synthesis/rules/IntegerInequalities.scala @@ -31,7 +31,7 @@ class IntegerInequalities(synth: Synthesizer) extends Rule("Integer Inequalities val ineqVars = lhsSides.foldLeft(Set[Identifier]())((acc, lhs) => acc ++ variablesOf(lhs)) val nonIneqVars = exprNotUsed.foldLeft(Set[Identifier]())((acc, x) => acc ++ variablesOf(x)) val candidateVars = ineqVars.intersect(problem.xs.toSet).filterNot(nonIneqVars.contains(_)) - if(candidateVars.isEmpty) RuleInapplicable else { + if(candidateVars.isEmpty) RuleInapplicable() else { val processedVar = candidateVars.head val otherVars: List[Identifier] = problem.xs.filterNot(_ == processedVar) diff --git a/src/main/scala/leon/synthesis/rules/OnePoint.scala b/src/main/scala/leon/synthesis/rules/OnePoint.scala index 1ee39b2d1..40f7da864 100644 --- a/src/main/scala/leon/synthesis/rules/OnePoint.scala +++ b/src/main/scala/leon/synthesis/rules/OnePoint.scala @@ -40,7 +40,7 @@ class OnePoint(synth: Synthesizer) extends Rule("One-point", synth, 300) { RuleOneStep(List(newProblem), onSuccess) } else { - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/rules/OptimisticGround.scala b/src/main/scala/leon/synthesis/rules/OptimisticGround.scala index 193380720..390f41c39 100644 --- a/src/main/scala/leon/synthesis/rules/OptimisticGround.scala +++ b/src/main/scala/leon/synthesis/rules/OptimisticGround.scala @@ -42,25 +42,25 @@ class OptimisticGround(synth: Synthesizer) extends Rule("Optimistic Ground", syn result = Some(RuleSuccess(Solution(BooleanLiteral(true), Set(), Tuple(p.xs.map(valuateWithModel(satModel))).setType(tpe)))) case _ => - result = Some(RuleInapplicable) + result = Some(RuleInapplicable()) } case (Some(false), _) => if (predicates.isEmpty) { result = Some(RuleSuccess(Solution(BooleanLiteral(false), Set(), Error(p.phi+" is UNSAT!").setType(tpe)))) } else { - result = Some(RuleInapplicable) + result = Some(RuleInapplicable()) } case _ => - result = Some(RuleInapplicable) + result = Some(RuleInapplicable()) } i += 1 } - result.getOrElse(RuleInapplicable) + result.getOrElse(RuleInapplicable()) } else { - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/rules/UnconstrainedOutput.scala b/src/main/scala/leon/synthesis/rules/UnconstrainedOutput.scala index a804d9cfc..021a68204 100644 --- a/src/main/scala/leon/synthesis/rules/UnconstrainedOutput.scala +++ b/src/main/scala/leon/synthesis/rules/UnconstrainedOutput.scala @@ -23,7 +23,7 @@ class UnconstrainedOutput(synth: Synthesizer) extends Rule("Unconstr.Output", sy RuleOneStep(List(sub), onSuccess) } else { - RuleInapplicable + RuleInapplicable() } } diff --git a/src/main/scala/leon/synthesis/rules/Unification.scala b/src/main/scala/leon/synthesis/rules/Unification.scala index 90a5c8741..e1412874f 100644 --- a/src/main/scala/leon/synthesis/rules/Unification.scala +++ b/src/main/scala/leon/synthesis/rules/Unification.scala @@ -31,7 +31,7 @@ object Unification { RuleOneStep(List(sub), forward) } else { - RuleInapplicable + RuleInapplicable() } } } @@ -56,7 +56,7 @@ object Unification { RuleSuccess(Solution(BooleanLiteral(false), Set(), Error(p.phi+" is UNSAT!").setType(tpe))) } else { - RuleInapplicable + RuleInapplicable() } } } diff --git a/src/main/scala/leon/synthesis/rules/UnusedInput.scala b/src/main/scala/leon/synthesis/rules/UnusedInput.scala index e9e0c18d6..482d594a1 100644 --- a/src/main/scala/leon/synthesis/rules/UnusedInput.scala +++ b/src/main/scala/leon/synthesis/rules/UnusedInput.scala @@ -16,7 +16,7 @@ class UnusedInput(synth: Synthesizer) extends Rule("UnusedInput", synth, 100) { RuleOneStep(List(sub), forward) } else { - RuleInapplicable + RuleInapplicable() } } } -- GitLab