@@ -56,6 +56,16 @@ class VarContext(val inputVariables: Set[Identifier], val outputVariables: Set[I
5656 FreshIdentifier (ov.name, IntegerType , false )
5757 }
5858 }
59+
60+ def newIdentifierName (init : String = " " ): String = {
61+ for (i <- 0 until 26 ) {
62+ val c = init + ('a' .toInt + i).toChar.toString
63+ if (idToInputVar.iterator.forall(_._1.name != c) && idToOutputVar.iterator.forall(_._1.name != c)) {
64+ return c
65+ }
66+ }
67+ newIdentifierName(init + " a" )
68+ }
5969}
6070
6171case class NotInputVarException (msg : String ) extends Exception (msg)
@@ -67,7 +77,8 @@ object ComfusyConverters {
6777 case Minus (a, b) => convertToAPAInputTerm(a) - convertToAPAInputTerm(b)
6878 case UMinus (a) => - convertToAPAInputTerm(a)
6979 case Times (a, b) => convertToAPAInputTerm(a) * convertToAPAInputTerm(b)
70- case Division (a, b) => convertToAPAInputTerm(a) / convertToAPAInputTerm(b)
80+ case Division (a, b) => convertToAPAInputTerm(a) / convertToAPAInputTerm(b).assumeNotZero()
81+ case purescala.Expressions .Assert (_, Some (" Division by zero" ), a) => convertToAPAInputTerm(a)
7182 case IfExpr (LessEquals (a1, InfiniteIntegerLiteral (zero)), UMinus (a2), a3) if a1 == a2 && a2 == a3 && zero == BigInt (0 ) => APAInputAbs (convertToAPAInputTerm(a1))
7283 // APAInputMod is not supported in Comfusy
7384 case Variable (i) if vc.inputVariables contains i => APAInputCombination (0 , (1 , vc.getInputVar(i)):: Nil )
@@ -102,6 +113,7 @@ object ComfusyConverters {
102113 case UMinus (a) => aux(a)
103114 case Times (a, b) => aux(a) && aux(b)
104115 case Division (a, b) => aux(a) && aux(b)
116+ case purescala.Expressions .Assert (_, Some (" Division by zero" ), a) => aux(a)
105117 // case Remainder(a, b) => aux(a) && aux(b)
106118 // case Modulo(a, b) => aux(a) && aux(b)
107119 case Variable (i) => vc.inputVariables contains i
@@ -174,7 +186,7 @@ object ComfusyConverters {
174186 val listType = LeonList .get
175187 val applyfun = vc.sctx.program.library.lookupUnique[FunDef ](" leon.collection.List.apply" )
176188 val bezoutWithBase = vc.sctx.program.library.bezoutWithBase.get
177- val b = FreshIdentifier (" b " , listType.typed(Seq (listType.typed(Seq (IntegerType )))), false )
189+ val b = FreshIdentifier (vc.newIdentifierName() , listType.typed(Seq (listType.typed(Seq (IntegerType )))), false )
178190 val decomposed : List [Expr => Expr ] = vs.zipWithIndex.map{ case (lv, i) =>
179191 lv.zipWithIndex.map { case (v, j) =>
180192 (w : Expr ) =>
@@ -196,6 +208,8 @@ object ComfusyConverters {
196208
197209 def APASplitConditionToExpr (sc : APASplitCondition )(implicit vc : VarContext ): Expr = sc match {
198210 case APAEmptySplitCondition () => BooleanLiteral (true )
211+ case APACaseSplitCondition (Nil ) => BooleanLiteral (true )
212+ case APACaseSplitCondition (a:: Nil ) => APAAbstractConditionToExpr (a)
199213 case APACaseSplitCondition (csl) => Or (csl.map(e => APAAbstractConditionToExpr (e)))
200214 case APAForCondition (vl, lower_range, upper_range, global_condition) =>
201215 val range = vc.sctx.program.library.lookupUnique[FunDef ](" leon.collection.List.range" )
@@ -266,7 +280,7 @@ object ComfusyConverters {
266280 def APAProgramToExpr (prog : APAProgram , expected_output_vars : List [OutputVar ])(implicit vc : VarContext ): Expr = {
267281 val assigns = ListInputAssignmentToExpr (prog.input_assignment)
268282 val affectedOutputVariables = prog.output_assignment.map(_._1).toSet
269- val referedOutputVariables = prog.output_assignment.flatMap(_._2.output_variables) filterNot affectedOutputVariables
283+ val referedOutputVariables = (expected_output_vars ++ prog.output_assignment.flatMap(_._2.output_variables) ) filterNot affectedOutputVariables
270284 val assignMiddle = APASplitToExpr (prog.case_splits, referedOutputVariables)
271285 val assigns2 = ListOutputAssignmentToExpr (prog.output_assignment)
272286 val output_expr = tupleWrap(expected_output_vars.map(ov => Variable (vc.getIdentifier(ov))))
@@ -354,7 +368,14 @@ object ComfusyConverters {
354368 case APAInputCombination (coef, input_linear) =>
355369 ((InfiniteIntegerLiteral (BigInt (coef)): Expr ) /: input_linear) { (c : Expr , iv) =>
356370 val (i, v) = iv
357- Plus (c, Times (InfiniteIntegerLiteral (i), Variable (vc.getIdentifier(v))))
371+ val newTerm = if ( i == BigInt (1 ) )
372+ Variable (vc.getIdentifier(v))
373+ else
374+ Times (InfiniteIntegerLiteral (i), Variable (vc.getIdentifier(v)))
375+ if ( c == InfiniteIntegerLiteral (BigInt (0 )))
376+ newTerm
377+ else
378+ Plus (c, newTerm)
358379 }
359380 case APAInputDivision (numerator, denominator) =>
360381 Division (APAInputTermToExpr (APAInputMultiplication (numerator)), APAInputTermToExpr (APAInputMultiplication (denominator)))
@@ -523,6 +544,7 @@ case object IntegerEquality extends Rule("Solve integer equality"){
523544 val (cond, prog) = problem.solve()
524545 // println(s"Solution condition = $cond under program = $prog")
525546 val solution = convertToSolution(cond, prog)
547+ // println(s"Rendered to $solution")
526548 RuleClosed (solution)
527549 })
528550 }
0 commit comments