diff --git a/src/main/scala/leon/repair/rules/Focus.scala b/src/main/scala/leon/repair/rules/Focus.scala index 943a5a67f094aea19f1c3903da6b0a32b19e10ec..7ce3fd261cbd4b9f28fae11517bb7640895f5517 100644 --- a/src/main/scala/leon/repair/rules/Focus.scala +++ b/src/main/scala/leon/repair/rules/Focus.scala @@ -164,7 +164,7 @@ case object Focus extends PreprocessingRule("Focus") { val eb3 = if (vars.nonEmpty) { eb2.mapIns(ebF) } else { - eb2 + eb2.eb } val newPc = andJoin(cond +: vars.map { id => equality(id.toVariable, map(id)) }) diff --git a/src/main/scala/leon/synthesis/ExamplesBank.scala b/src/main/scala/leon/synthesis/ExamplesBank.scala index 1da37b3509f4abdd0a8b3ecbdd329b55ab16f45f..35a6986864dde1a97fdca214536dac6a21b52c57 100644 --- a/src/main/scala/leon/synthesis/ExamplesBank.scala +++ b/src/main/scala/leon/synthesis/ExamplesBank.scala @@ -160,38 +160,44 @@ case class ExamplesBank(valids: Seq[Example], invalids: Seq[Example]) { object ExamplesBank { def empty = ExamplesBank(Nil, Nil) + } /** Same as an ExamplesBank, but with identifiers corresponding to values. This * allows us to evaluate expressions. */ case class QualifiedExamplesBank(as: List[Identifier], xs: List[Identifier], eb: ExamplesBank)(implicit hctx: SearchContext) { - def removeOuts(toRemove: Set[Identifier]) = { + def removeOuts(toRemove: Set[Identifier]): QualifiedExamplesBank = { + val nxs = xs.filterNot(toRemove) val toKeep = xs.zipWithIndex.filterNot(x => toRemove(x._1)).map(_._2) - eb mapOuts { out => List(toKeep.map(out)) } + QualifiedExamplesBank(as, nxs, eb mapOuts { out => List(toKeep.map(out)) }) } def removeIns(toRemove: Set[Identifier]) = { + val nas = as.filterNot(toRemove) val toKeep: List[Int] = as.zipWithIndex.filterNot(a => toRemove(a._1)).map(_._2) - eb mapIns { (in: Seq[Expr]) => List(toKeep.map(in)) } + + QualifiedExamplesBank(nas, xs, eb mapIns { (in: Seq[Expr]) => List(toKeep.map(in)) }) } /** Filter inputs throught expr which is an expression evaluating to a boolean */ - def filterIns(expr: Expr): ExamplesBank = { + def filterIns(expr: Expr): QualifiedExamplesBank = { filterIns(m => hctx.defaultEvaluator.eval(expr, m).result == Some(BooleanLiteral(true))) } /** Filters inputs through the predicate pred, with an assignment of input variables to expressions. */ - def filterIns(pred: Map[Identifier, Expr] => Boolean): ExamplesBank = { - eb mapIns { in => - val m = (as zip in).toMap - if(pred(m)) { - List(in) - } else { - Nil + def filterIns(pred: Map[Identifier, Expr] => Boolean): QualifiedExamplesBank = { + QualifiedExamplesBank(as, xs, + eb mapIns { in => + val m = (as zip in).toMap + if(pred(m)) { + List(in) + } else { + Nil + } } - } + ) } /** Maps inputs through the function f @@ -206,3 +212,9 @@ case class QualifiedExamplesBank(as: List[Identifier], xs: List[Identifier], eb: } } } + +import scala.language.implicitConversions + +object QualifiedExamplesBank { + implicit def qebToEb(qeb: QualifiedExamplesBank): ExamplesBank = qeb.eb +} diff --git a/src/main/scala/leon/synthesis/Rules.scala b/src/main/scala/leon/synthesis/Rules.scala index f55c670f4515070a1d0ccb5bd02b33b24bf9c22f..ff92b251e76cce8508629fe3cafeb9e40f37cb74 100644 --- a/src/main/scala/leon/synthesis/Rules.scala +++ b/src/main/scala/leon/synthesis/Rules.scala @@ -51,26 +51,15 @@ object Rules { UnusedInput, EquivalentInputs, UnconstrainedOutput, + if(naiveGrammar) NaiveCEGIS else CEGIS, OptimisticGround, - EqualitySplit, + GenericTypeEqualitySplit, InequalitySplit, IntroduceRecCalls, - if(naiveGrammar) NaiveCEGIS else CEGIS, - //TEGIS, - //BottomUpTEGIS, rules.Assert, - //DetupleOutput, // Subsumed by IndependentSplit DetupleInput, ADTSplit, - //IntegerEquation, - //IntegerInequalities, - IntInduction, InnerCaseSplit - //new OptimisticInjection(_), - //new SelectiveInlining(_), - //ADTLongInduction, - //ADTInduction - //AngelicHoles // @EK: Disabled now as it is explicit with withOracle { .. } ) } @@ -212,20 +201,4 @@ trait RuleDSL { case _ => None } - - /** Straightforward combination of solutions, where expression is reconstructed according to a combiner. - * If combiner fails, no solution will be returned. - * - * @param combiner The combiner of synthesized subterms which reconstructs the term of the solution from the subterms. - */ - def simpleCombine(combiner: PartialFunction[List[Expr], Expr]): List[Solution] => Option[Solution] = { ls => - combiner.lift(ls map (_.term)).map{ combined => - Solution( - orJoin(ls map (_.pre)), - ls.flatMap (_.defs).toSet, - combined, - ls.forall(_.isTrusted) - ) - } - } } diff --git a/src/main/scala/leon/synthesis/rules/EqualitySplit.scala b/src/main/scala/leon/synthesis/rules/EqualitySplit.scala deleted file mode 100644 index 6f6eea54f5a5647aed883a2e8de68508e1fdd950..0000000000000000000000000000000000000000 --- a/src/main/scala/leon/synthesis/rules/EqualitySplit.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright 2009-2016 EPFL, Lausanne */ - -package leon -package synthesis -package rules - -import purescala.Common.Identifier -import purescala.Expressions._ -import purescala.Extractors._ -import purescala.Constructors._ - -/** For every pair of input variables of the same type, - * checks equality and output an If-Then-Else statement with the two new branches. */ -case object EqualitySplit extends Rule("Eq. Split") { - def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = { - // We approximate knowledge of equality based on facts found at the top-level - // we don't care if the variables are known to be equal or not, we just - // don't want to split on two variables for which only one split - // alternative is viable. This should be much less expensive than making - // calls to a solver for each pair. - var facts = Set[Set[Identifier]]() - - def addFacts(e: Expr): Unit = e match { - case Not(e) => addFacts(e) - case LessThan(Variable(a), Variable(b)) => facts += Set(a,b) - case LessEquals(Variable(a), Variable(b)) => facts += Set(a,b) - case GreaterThan(Variable(a), Variable(b)) => facts += Set(a,b) - case GreaterEquals(Variable(a), Variable(b)) => facts += Set(a,b) - case Equals(Variable(a), Variable(b)) => facts += Set(a,b) - case _ => - } - - val TopLevelAnds(as) = and(p.pc, p.phi) - for (e <- as) { - addFacts(e) - } - - val candidates = p.as.groupBy(_.getType).mapValues{ as => - as.combinations(2).filterNot(facts contains _.toSet) - }.values.flatten - - candidates.flatMap { - case List(a1, a2) => - - val sub1 = p.copy( - pc = and(Equals(Variable(a1), Variable(a2)), p.pc), - eb = p.qeb.filterIns( (m: Map[Identifier, Expr]) => m(a1) == m(a2)) - ) - val sub2 = p.copy( - pc = and(not(Equals(Variable(a1), Variable(a2))), p.pc), - eb = p.qeb.filterIns( (m: Map[Identifier, Expr]) => m(a1) != m(a2)) - ) - - val onSuccess = simpleCombine { case List(s1, s2) => IfExpr(Equals(Variable(a1), Variable(a2)), s1, s2) } - - Some(decomp(List(sub1, sub2), onSuccess, s"Eq. Split on '$a1' and '$a2'")) - case _ => - None - } - } -} diff --git a/src/main/scala/leon/synthesis/rules/GenericTypeEqualitySplit.scala b/src/main/scala/leon/synthesis/rules/GenericTypeEqualitySplit.scala new file mode 100644 index 0000000000000000000000000000000000000000..8dce44d6878ad24ed96dd5c33b9461100cd9f417 --- /dev/null +++ b/src/main/scala/leon/synthesis/rules/GenericTypeEqualitySplit.scala @@ -0,0 +1,72 @@ +/* Copyright 2009-2016 EPFL, Lausanne */ + +package leon +package synthesis +package rules + +import leon.purescala.Common.Identifier +import purescala.Constructors._ +import purescala.Expressions._ +import leon.purescala.Extractors.{IsTyped, TopLevelAnds} +import purescala.Types._ + +/** For every pair of input variables of the same generic type, + * checks equality and output an If-Then-Else statement with the two new branches. + */ +case object GenericTypeEqualitySplit extends Rule("Eq. Split") { + def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = { + // We approximate knowledge of equality based on facts found at the top-level + // we don't care if the variables are known to be equal or not, we just + // don't want to split on two variables for which only one split + // alternative is viable. This should be much less expensive than making + // calls to a solver for each pair. + def getFacts(e: Expr): Set[Set[Identifier]] = e match { + case Not(e) => getFacts(e) + case Equals(Variable(a), Variable(b)) => Set(Set(a,b)) + case _ => Set() + } + + val TopLevelAnds(as) = and(p.pc, p.phi) + + val facts = as.flatMap(getFacts).toSet + + val candidates = p.as.combinations(2).collect { + case List(IsTyped(a1, TypeParameter(t1)), IsTyped(a2, TypeParameter(t2))) + if t1 == t2 && !facts(Set(a1, a2)) => + (a1, a2) + }.toList + + candidates.flatMap { + case (a1, a2) => + val v1 = Variable(a1) + val v2 = Variable(a2) + val subProblems = List( + p.copy(as = p.as.diff(Seq(a1)), + pc = subst(a1 -> v2, p.pc), + ws = subst(a1 -> v2, p.ws), + phi = subst(a1 -> v2, p.phi), + eb = p.qeb.filterIns(Equals(v1, v2)).removeIns(Set(a1))), + + p.copy(pc = and(p.pc, not(Equals(v1, v2))), + eb = p.qeb.filterIns(not(Equals(v1, v2)))) + ) + + val onSuccess: List[Solution] => Option[Solution] = { + case sols @ List(sEQ, sNE) => + val pre = or( + and(Equals(v1, v2), sEQ.pre), + and(not(Equals(v1, v2)), sNE.pre) + ) + + val term = IfExpr(Equals(v1, v2), sEQ.term, sNE.term) + + Some(Solution(pre, sols.flatMap(_.defs).toSet, term, sols.forall(_.isTrusted))) + } + + Some(decomp(subProblems, onSuccess, s"Eq. Split on '$v1' and '$v2'")) + + case _ => + None + } + } +} diff --git a/src/main/scala/leon/synthesis/rules/InequalitySplit.scala b/src/main/scala/leon/synthesis/rules/InequalitySplit.scala index db41c6c3b45694c27af6c78b6fa420dcd3ca6324..54445a5d48dc199440366aa8ac302d1c075bd4c2 100644 --- a/src/main/scala/leon/synthesis/rules/InequalitySplit.scala +++ b/src/main/scala/leon/synthesis/rules/InequalitySplit.scala @@ -8,65 +8,99 @@ import purescala.Expressions._ import purescala.Types._ import purescala.Constructors._ import purescala.Extractors._ -import purescala.Common._ +/** For every pair of variables of an integer type plus 0 of that type, + * splits for inequality between these variables + * and reconstructs the subproblems with a (nested) if-then-else. + * + * Takes into account knowledge about equality/inequality in the path condition. + * + */ case object InequalitySplit extends Rule("Ineq. Split.") { + + // Represents NEGATIVE knowledge + private abstract class Fact { + val l: Expr + val r: Expr + } + private case class LT(l: Expr, r: Expr) extends Fact + private case class EQ(l: Expr, r: Expr) extends Fact + def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = { - // We approximate knowledge of equality based on facts found at the top-level - // we don't care if the variables are known to be equal or not, we just - // don't want to split on two variables for which only one split - // alternative is viable. This should be much less expensive than making - // calls to a solver for each pair. val TopLevelAnds(as) = and(p.pc, p.phi) - def addFacts(e: Expr): Set[Identifier] = e match { - case Not(e) => addFacts(e) - case LessThan(Variable(a), Variable(b)) => Set(a,b) - case LessEquals(Variable(a), Variable(b)) => Set(a,b) - case GreaterThan(Variable(a), Variable(b)) => Set(a,b) - case GreaterEquals(Variable(a), Variable(b)) => Set(a,b) - case Equals(Variable(a), Variable(b)) => Set(a,b) + + def getFacts(e: Expr): Set[Fact] = e match { + case LessThan(a, b) => Set(LT(b,a), EQ(a,b)) + case LessEquals(a, b) => Set(LT(b,a)) + case GreaterThan(a, b) => Set(LT(a,b), EQ(a,b)) + case GreaterEquals(a, b) => Set(LT(a,b)) + case Equals(a, b) => Set(LT(a,b), LT(b,a)) + case Not(LessThan(a, b)) => Set(LT(a,b)) + case Not(LessEquals(a, b)) => Set(LT(a,b), EQ(a,b)) + case Not(GreaterThan(a, b)) => Set(LT(b,a)) + case Not(GreaterEquals(a, b)) => Set(LT(b,a), EQ(a,b)) + case Not(Equals(a, b)) => Set(EQ(a,b)) case _ => Set() } - val facts = as map addFacts - - val argsPairs = p.as.filter(_.getType == IntegerType).combinations(2) ++ - p.as.filter(_.getType == Int32Type).combinations(2) - - val candidates = argsPairs.toList.filter { case List(a1, a2) => !(facts contains Set(a1, a2)) } - - candidates.collect { - case List(a1, a2) => - val onSuccess = simpleCombine { - case sols@List(sLT, sEQ, sGT) => - IfExpr( - LessThan(Variable(a1), Variable(a2)), - sLT, - IfExpr( - Equals(Variable(a1), Variable(a2)), - sEQ, - sGT - ) - ) - } - val subTypes = List(p.outType, p.outType, p.outType) + val facts = as flatMap getFacts + + val candidates = + (p.as.map(_.toVariable).filter(_.getType == Int32Type) :+ IntLiteral(0)).combinations(2).toList ++ + (p.as.map(_.toVariable).filter(_.getType == IntegerType) :+ InfiniteIntegerLiteral(0)).combinations(2).toList - new RuleInstantiation(s"Ineq. Split on '$a1' and '$a2'", - SolutionBuilderDecomp(subTypes, onSuccess)) { + candidates.flatMap { + case List(v1, v2) => - def apply(hctx: SearchContext) = { - implicit val _ = hctx + val lt = if (!facts.contains(LT(v1, v2))) { + val pc = LessThan(v1, v2) + Some(pc, p.copy(pc = and(p.pc, pc), eb = p.qeb.filterIns(pc))) + } else None - val subLT = p.copy(pc = and(LessThan(Variable(a1), Variable(a2)), p.pc), - eb = p.qeb.filterIns(LessThan(Variable(a1), Variable(a2)))) - val subEQ = p.copy(pc = and(Equals(Variable(a1), Variable(a2)), p.pc), - eb = p.qeb.filterIns(Equals(Variable(a1), Variable(a2)))) - val subGT = p.copy(pc = and(GreaterThan(Variable(a1), Variable(a2)), p.pc), - eb = p.qeb.filterIns(GreaterThan(Variable(a1), Variable(a2)))) + val gt = if (!facts.contains(LT(v2, v1))) { + val pc = GreaterThan(v1, v2) + Some(pc, p.copy(pc = and(p.pc, pc), eb = p.qeb.filterIns(pc))) + } else None - RuleExpanded(List(subLT, subEQ, subGT)) + val eq = if (!facts.contains(EQ(v1, v2)) && !facts.contains(EQ(v2,v1))) { + val pc = Equals(v1, v2) + // One of v1, v2 will be an input variable + val a1 = (v1, v2) match { + case (Variable(a), _) => a + case (_, Variable(a)) => a } + val newP = p.copy( + as = p.as.diff(Seq(a1)), + pc = subst(a1 -> v2, p.pc), + ws = subst(a1 -> v2, p.ws), + phi = subst(a1 -> v2, p.phi), + eb = p.qeb.filterIns(Equals(v1, v2)).removeIns(Set(a1)) + ) + Some(pc, newP) + } else None + + val (pcs, subProblems) = List(eq, lt, gt).flatten.unzip + + if (pcs.size < 2) None + else { + + val onSuccess: List[Solution] => Option[Solution] = { sols => + val pre = orJoin(pcs.zip(sols).map { case (pc, sol) => + and(pc, sol.pre) + }) + + val term = pcs.zip(sols) match { + case Seq((pc1, s1), (_, s2)) => + IfExpr(pc1, s1.term, s2.term) + case Seq((pc1, s1), (pc2, s2), (_, s3)) => + IfExpr(pc1, s1.term, IfExpr(pc2, s2.term, s3.term)) + } + + Some(Solution(pre, sols.flatMap(_.defs).toSet, term, sols.forall(_.isTrusted))) + } + + Some(decomp(subProblems, onSuccess, s"Ineq. Split on '$v1' and '$v2'")) } } } diff --git a/src/main/scala/leon/synthesis/rules/ADTInduction.scala b/src/main/scala/leon/synthesis/rules/unused/ADTInduction.scala similarity index 99% rename from src/main/scala/leon/synthesis/rules/ADTInduction.scala rename to src/main/scala/leon/synthesis/rules/unused/ADTInduction.scala index 90738c698c1947b197406e61390c0ba0ca628b7a..ab2720fb00f620c0800d6936c9e97b3be3deedac 100644 --- a/src/main/scala/leon/synthesis/rules/ADTInduction.scala +++ b/src/main/scala/leon/synthesis/rules/unused/ADTInduction.scala @@ -2,7 +2,7 @@ package leon package synthesis -package rules +package rules.unused import purescala.Common._ import purescala.Expressions._ diff --git a/src/main/scala/leon/synthesis/rules/ADTLongInduction.scala b/src/main/scala/leon/synthesis/rules/unused/ADTLongInduction.scala similarity index 99% rename from src/main/scala/leon/synthesis/rules/ADTLongInduction.scala rename to src/main/scala/leon/synthesis/rules/unused/ADTLongInduction.scala index d14c2b0f8538a61dd0ce8c3ae507f05bcc79c2f7..4ffd1a8c258a48007959f87cfb861812959517a8 100644 --- a/src/main/scala/leon/synthesis/rules/ADTLongInduction.scala +++ b/src/main/scala/leon/synthesis/rules/unused/ADTLongInduction.scala @@ -2,7 +2,7 @@ package leon package synthesis -package rules +package rules.unused import purescala.Common._ import purescala.Expressions._ diff --git a/src/main/scala/leon/synthesis/rules/AsChoose.scala b/src/main/scala/leon/synthesis/rules/unused/AsChoose.scala similarity index 79% rename from src/main/scala/leon/synthesis/rules/AsChoose.scala rename to src/main/scala/leon/synthesis/rules/unused/AsChoose.scala index 7f231b85df8c57f3a87e60f88030679024bf30d6..06270b939929a96985719b78a3f58ee58d9ce931 100644 --- a/src/main/scala/leon/synthesis/rules/AsChoose.scala +++ b/src/main/scala/leon/synthesis/rules/unused/AsChoose.scala @@ -1,8 +1,8 @@ /* Copyright 2009-2016 EPFL, Lausanne */ -package leon -package synthesis -package rules +package leon.synthesis.rules.unused + +import leon.synthesis._ case object AsChoose extends Rule("As Choose") { def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = { diff --git a/src/main/scala/leon/synthesis/rules/BottomUpTegis.scala b/src/main/scala/leon/synthesis/rules/unused/BottomUpTegis.scala similarity index 99% rename from src/main/scala/leon/synthesis/rules/BottomUpTegis.scala rename to src/main/scala/leon/synthesis/rules/unused/BottomUpTegis.scala index 5dbcbb3a131deab0cf091778771a328ae9a47379..8f82395a55c522a8a84a9aa463e0e704cd89beed 100644 --- a/src/main/scala/leon/synthesis/rules/BottomUpTegis.scala +++ b/src/main/scala/leon/synthesis/rules/unused/BottomUpTegis.scala @@ -2,7 +2,7 @@ package leon package synthesis -package rules +package rules.unused import purescala.Expressions._ import purescala.Common._ diff --git a/src/main/scala/leon/synthesis/rules/DetupleOutput.scala b/src/main/scala/leon/synthesis/rules/unused/DetupleOutput.scala similarity index 98% rename from src/main/scala/leon/synthesis/rules/DetupleOutput.scala rename to src/main/scala/leon/synthesis/rules/unused/DetupleOutput.scala index a1d2193409788cd54d25639d6900dc5b9301ec33..18067e9529596329d44cacf9672931c6e0178414 100644 --- a/src/main/scala/leon/synthesis/rules/DetupleOutput.scala +++ b/src/main/scala/leon/synthesis/rules/unused/DetupleOutput.scala @@ -2,7 +2,7 @@ package leon package synthesis -package rules +package rules.unused import purescala.Expressions._ import purescala.Common._ diff --git a/src/main/scala/leon/synthesis/rules/IntInduction.scala b/src/main/scala/leon/synthesis/rules/unused/IntInduction.scala similarity index 95% rename from src/main/scala/leon/synthesis/rules/IntInduction.scala rename to src/main/scala/leon/synthesis/rules/unused/IntInduction.scala index bfebd3929b8155b154590c798272df4c2aeba1a1..6ef209fcb386a98046a0bd107dd94d4aa3c31403 100644 --- a/src/main/scala/leon/synthesis/rules/IntInduction.scala +++ b/src/main/scala/leon/synthesis/rules/unused/IntInduction.scala @@ -2,14 +2,14 @@ package leon package synthesis -package rules +package rules.unused -import purescala.Common._ -import purescala.Expressions._ -import purescala.Extractors._ +import purescala.Common.FreshIdentifier import purescala.Constructors._ -import purescala.Types._ -import purescala.Definitions._ +import purescala.Definitions.{FunDef, ValDef} +import purescala.Expressions._ +import purescala.Extractors.IsTyped +import purescala.Types.IntegerType case object IntInduction extends Rule("Int Induction") { def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = { diff --git a/src/main/scala/leon/synthesis/rules/IntegerEquation.scala b/src/main/scala/leon/synthesis/rules/unused/IntegerEquation.scala similarity index 99% rename from src/main/scala/leon/synthesis/rules/IntegerEquation.scala rename to src/main/scala/leon/synthesis/rules/unused/IntegerEquation.scala index f51d9007564414836852324b46ba84b473f0714c..fdb59b00d7afabcb089b100a85381e646c89f5c7 100644 --- a/src/main/scala/leon/synthesis/rules/IntegerEquation.scala +++ b/src/main/scala/leon/synthesis/rules/unused/IntegerEquation.scala @@ -2,7 +2,7 @@ package leon package synthesis -package rules +package rules.unused import purescala.Common._ import purescala.Expressions._ diff --git a/src/main/scala/leon/synthesis/rules/IntegerInequalities.scala b/src/main/scala/leon/synthesis/rules/unused/IntegerInequalities.scala similarity index 99% rename from src/main/scala/leon/synthesis/rules/IntegerInequalities.scala rename to src/main/scala/leon/synthesis/rules/unused/IntegerInequalities.scala index dfb1fa8d6db8b49ae80a5e2062db9fd2b0b2b6be..602a7e61ba1e94c174f44cc71c04790feeb636f6 100644 --- a/src/main/scala/leon/synthesis/rules/IntegerInequalities.scala +++ b/src/main/scala/leon/synthesis/rules/unused/IntegerInequalities.scala @@ -2,7 +2,7 @@ package leon package synthesis -package rules +package rules.unused import purescala.Common._ import purescala.Expressions._ diff --git a/src/main/scala/leon/synthesis/rules/OptimisticInjection.scala b/src/main/scala/leon/synthesis/rules/unused/OptimisticInjection.scala similarity index 98% rename from src/main/scala/leon/synthesis/rules/OptimisticInjection.scala rename to src/main/scala/leon/synthesis/rules/unused/OptimisticInjection.scala index 599fbd5df54d4750b5021916eecc5103e126b57a..b3d35f8a090d8f1b85532040b558cb8abf5a0c8f 100644 --- a/src/main/scala/leon/synthesis/rules/OptimisticInjection.scala +++ b/src/main/scala/leon/synthesis/rules/unused/OptimisticInjection.scala @@ -2,7 +2,7 @@ package leon package synthesis -package rules +package rules.unused import purescala.Expressions._ import purescala.Extractors._ diff --git a/src/main/scala/leon/synthesis/rules/SelectiveInlining.scala b/src/main/scala/leon/synthesis/rules/unused/SelectiveInlining.scala similarity index 90% rename from src/main/scala/leon/synthesis/rules/SelectiveInlining.scala rename to src/main/scala/leon/synthesis/rules/unused/SelectiveInlining.scala index 4469382133c2ee4eb09424b07266382aafa1a0c6..9dd4e68e01ede5e953c3b0f06a573be505056dc3 100644 --- a/src/main/scala/leon/synthesis/rules/SelectiveInlining.scala +++ b/src/main/scala/leon/synthesis/rules/unused/SelectiveInlining.scala @@ -2,11 +2,11 @@ package leon package synthesis -package rules +package rules.unused -import purescala.Expressions._ -import purescala.Extractors._ import purescala.Constructors._ +import purescala.Expressions.{Equals, Expr, FunctionInvocation} +import purescala.Extractors.TopLevelAnds case object SelectiveInlining extends Rule("Sel. Inlining") { def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = { diff --git a/src/main/scala/leon/synthesis/rules/SygusCVC4.scala b/src/main/scala/leon/synthesis/rules/unused/SygusCVC4.scala similarity index 90% rename from src/main/scala/leon/synthesis/rules/SygusCVC4.scala rename to src/main/scala/leon/synthesis/rules/unused/SygusCVC4.scala index d458de88caf44c03acd12dab1d0b1ce42c59767f..800d1e5f84c3067fe94fb368a82f1302a8981c43 100644 --- a/src/main/scala/leon/synthesis/rules/SygusCVC4.scala +++ b/src/main/scala/leon/synthesis/rules/unused/SygusCVC4.scala @@ -2,9 +2,9 @@ package leon package synthesis -package rules +package rules.unused -import solvers.sygus._ +import leon.solvers.sygus.CVC4SygusSolver case object SygusCVC4 extends Rule("SygusCVC4") { def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = { diff --git a/src/main/scala/leon/synthesis/rules/TEGIS.scala b/src/main/scala/leon/synthesis/rules/unused/TEGIS.scala similarity index 94% rename from src/main/scala/leon/synthesis/rules/TEGIS.scala rename to src/main/scala/leon/synthesis/rules/unused/TEGIS.scala index 242502a169ff1107ad9ace70e5cef240c269b7f6..7b08304dcf7735649f3e7ec760a9cba73fe6caaa 100644 --- a/src/main/scala/leon/synthesis/rules/TEGIS.scala +++ b/src/main/scala/leon/synthesis/rules/unused/TEGIS.scala @@ -2,7 +2,7 @@ package leon package synthesis -package rules +package rules.unused import purescala.Types._ import grammars._ diff --git a/src/main/scala/leon/synthesis/rules/TEGISLike.scala b/src/main/scala/leon/synthesis/rules/unused/TEGISLike.scala similarity index 99% rename from src/main/scala/leon/synthesis/rules/TEGISLike.scala rename to src/main/scala/leon/synthesis/rules/unused/TEGISLike.scala index a085ad4366ea1f852b0ad714c713a5943fb269fd..cd6382864163d11c770386f09804d0504d2702fa 100644 --- a/src/main/scala/leon/synthesis/rules/TEGISLike.scala +++ b/src/main/scala/leon/synthesis/rules/unused/TEGISLike.scala @@ -2,7 +2,7 @@ package leon package synthesis -package rules +package rules.unused import purescala.Expressions._ import purescala.Types._ diff --git a/src/main/scala/leon/synthesis/rules/TEGLESS.scala b/src/main/scala/leon/synthesis/rules/unused/TEGLESS.scala similarity index 96% rename from src/main/scala/leon/synthesis/rules/TEGLESS.scala rename to src/main/scala/leon/synthesis/rules/unused/TEGLESS.scala index f87968ea3ae2da64110f77ff4fc9d7b627c2b487..a58a0b138d14f9aefc2fba71f16130a682f22968 100644 --- a/src/main/scala/leon/synthesis/rules/TEGLESS.scala +++ b/src/main/scala/leon/synthesis/rules/unused/TEGLESS.scala @@ -2,11 +2,10 @@ package leon package synthesis -package rules +package rules.unused import purescala.Types._ import purescala.Extractors._ -import utils._ import Witnesses._ import grammars._ diff --git a/src/main/scala/leon/synthesis/utils/Helpers.scala b/src/main/scala/leon/synthesis/utils/Helpers.scala index 87d9c587c6c0b9ce24bd09df5753f0a5bb02667d..a0b940958ffecee169005512693d00539ffef196 100644 --- a/src/main/scala/leon/synthesis/utils/Helpers.scala +++ b/src/main/scala/leon/synthesis/utils/Helpers.scala @@ -61,9 +61,19 @@ object Helpers { case _ => None } + val z = InfiniteIntegerLiteral(0) + val one = InfiniteIntegerLiteral(1) val knownSmallers = clauses.collect { case Equals(v: Variable, s@CaseClassSelector(cct, r, _)) => subExprsOf(s, v) case Equals(s@CaseClassSelector(cct, r, _), v: Variable) => subExprsOf(s, v) + case GreaterThan(v: Variable, `z`) => + Some(v -> Minus(v, one)) + case LessThan(`z`, v: Variable) => + Some(v -> Minus(v, one)) + case LessThan(v: Variable, `z`) => + Some(v -> Plus(v, one)) + case GreaterThan(`z`, v: Variable) => + Some(v -> Plus(v, one)) }.flatten.groupBy(_._1).mapValues(v => v.map(_._2)) def argsSmaller(e: Expr, tpe: TypeTree): Seq[Expr] = e match { @@ -74,7 +84,6 @@ object Helpers { }.flatten case v: Variable => knownSmallers.getOrElse(v, Seq()) - case _ => Nil } diff --git a/src/test/scala/leon/regression/synthesis/StablePrintingSuite.scala b/src/test/scala/leon/regression/synthesis/StablePrintingSuite.scala index da7f51f4fff9905542af4bfa471792da5ae86a20..6ab235dd5dda3f1c9e087ca0c93b374f07dec5df 100644 --- a/src/test/scala/leon/regression/synthesis/StablePrintingSuite.scala +++ b/src/test/scala/leon/regression/synthesis/StablePrintingSuite.scala @@ -42,10 +42,8 @@ class StablePrintingSuite extends LeonRegressionSuite { OptimisticGround, InequalitySplit, rules.Assert, - DetupleOutput, DetupleInput, ADTSplit, - IntInduction, InnerCaseSplit ) diff --git a/synthesis-collective.txt b/synthesis-collective.txt index 5085e1dcc7f19028cf0399be1894bc03c4b8ba4f..f2cbedc5d302beb3622dd326c0d702fdf4eef190 100644 --- a/synthesis-collective.txt +++ b/synthesis-collective.txt @@ -6,7 +6,7 @@ F = Timeout/failed to synth. ============================================================================ -Name | FDefs| Size | O-O-5 | O-O-7 |<current> | +Name | FDefs| Size | O-O-5 | O-O-7 | 0515ff9 | ============================================================================ List.insert | 59 | 3 | ✓ | 0.8 | ✓ | 1.0 | ✓ | 0.7 | List.delete | 61 | 0 | ✓ | 4.5 | F | 30.1 | ✓ | 3.2 | diff --git a/testcases/synthesis/current/RunLength/RunLength.scala b/testcases/synthesis/current/RunLength/RunLength.scala index fd886180e7b2a21f1ba65f2698e86eee2cdd2001..8813b97f71fe090ec6e73b75b396f0eb25f984a8 100644 --- a/testcases/synthesis/current/RunLength/RunLength.scala +++ b/testcases/synthesis/current/RunLength/RunLength.scala @@ -5,7 +5,6 @@ import leon.collection._ object RunLength { - def decode[A](l: List[(BigInt, A)]): List[A] = { def fill[A](i: BigInt, a: A): List[A] = { if (i > 0) a :: fill(i - 1, a) @@ -18,7 +17,6 @@ object RunLength { } } - def legal[A](l: List[(BigInt, A)]): Boolean = l match { case Cons((i, x), tl) => i > 0 && (tl match { @@ -28,12 +26,6 @@ object RunLength { case _ => true } - /*def unique[A](l1: List[A], l2: List[A]) => { - require(encode(l1) == encode(l2)) - l1 == l2 - }.holds*/ - - // Solvable with --manual=2,0,0,1,0,0,3,0,1,1,0,0,1,0,0,0,1,1,1 def encode[A](l: List[A]): List[(BigInt, A)] = { // Solution /*l match {