From 7d7d96fc7ddfb0dc6fe9ee7701c39a431c84cd08 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <ekneuss@gmail.com> Date: Mon, 12 Nov 2012 18:28:34 +0100 Subject: [PATCH] Work on the new CEGIS --- .../scala/leon/synthesis/Heuristics.scala | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/src/main/scala/leon/synthesis/Heuristics.scala b/src/main/scala/leon/synthesis/Heuristics.scala index ad716afe1..ce34ab79c 100644 --- a/src/main/scala/leon/synthesis/Heuristics.scala +++ b/src/main/scala/leon/synthesis/Heuristics.scala @@ -11,7 +11,8 @@ import purescala.Definitions._ object Heuristics { def all = Set[Synthesizer => Rule]( new OptimisticGround(_), - new IntInduction(_), + //new IntInduction(_), + new CEGISOnSteroids(_), new OptimisticInjection(_) ) } @@ -195,3 +196,88 @@ class SelectiveInlining(synth: Synthesizer) extends Rule("Sel. Inlining", synth, } } } + +class CEGISOnSteroids(synth: Synthesizer) extends Rule("cegis w. gen.", synth, 50) with Heuristic { + def applyOn(task: Task): RuleResult = { + val p = task.problem + + case class Generator(tpe: TypeTree, altBuilder: () => List[(Expr, Set[Identifier])]); + + var generators = Map[TypeTree, Generator]() + def getGenerator(t: TypeTree): Generator = generators.get(t) match { + case Some(g) => g + case None => + val alternatives: () => List[(Expr, Set[Identifier])] = t match { + case BooleanType => + { () => List((BooleanLiteral(true), Set()), (BooleanLiteral(false), Set())) } + + case Int32Type => + { () => List((IntLiteral(0), Set()), (IntLiteral(1), Set())) } + + case TupleType(tps) => + { () => + val ids = tps.map(t => FreshIdentifier("t", true).setType(t)) + List((Tuple(ids.map(Variable(_))), ids.toSet)) + } + + case CaseClassType(cd) => + { () => + val ids = cd.fieldsIds.map(i => FreshIdentifier("c", true).setType(i.getType)) + List((CaseClass(cd, ids.map(Variable(_))), ids.toSet)) + } + + case AbstractClassType(cd) => + { () => + val alts: Seq[(Expr, Set[Identifier])] = cd.knownDescendents.flatMap(i => i match { + case acd: AbstractClassDef => + synth.reporter.error("Unnexpected abstract class in descendants!") + None + case cd: CaseClassDef => + val ids = cd.fieldsIds.map(i => FreshIdentifier("c", true).setType(i.getType)) + Some((CaseClass(cd, ids.map(Variable(_))), ids.toSet)) + }) + alts.toList + } + + case _ => + synth.reporter.error("Can't construct generator. Unsupported type: "+t+"["+t.getClass+"]"); + { () => Nil } + } + val g = Generator(t, alternatives) + generators += t -> g + g + } + + case class TentativeFormula(f: Expr, recTerms: Map[Identifier, Set[Identifier]]) { + def unroll: TentativeFormula = { + var newF = this.f + var newRecTerms = Map[Identifier, Set[Identifier]]() + for ((_, recIds) <- recTerms; recId <- recIds) { + val gen = getGenerator(recId.getType) + val alts = gen.altBuilder().map(alt => FreshIdentifier("b", true) -> alt) + + val pre = Or(alts.map{ case (id, _) => Variable(id) }) // b1 OR b2 + val cases = for((bid, (ex, rec)) <- alts.toList) yield { // b1 => E(gen1, gen2) [b1 -> {gen1, gen2}] + if (!rec.isEmpty) { + newRecTerms += bid -> rec + } + Implies(Variable(bid), Equals(Variable(recId), ex)) + } + + newF = And(newF, And(pre :: cases)) + } + + TentativeFormula(newF, newRecTerms) + } + + def closedFormula = And(f :: recTerms.keySet.map(id => Not(Variable(id))).toList) + } + + println("Formula is: "+p.phi) + val initF = TentativeFormula(p.phi, Map() ++ p.xs.map(x => x -> Set(x))) // Set to expand on xs + println("unroll 1: "+initF.unroll.closedFormula) + println("unroll 2: "+initF.unroll.unroll.closedFormula) + + RuleInapplicable + } +} -- GitLab