Skip to content
Snippets Groups Projects
Commit 4dd4ad69 authored by Nicolas Voirol's avatar Nicolas Voirol
Browse files

Optimization for && and || short-circuiting

parent 6de88b1e
Branches
Tags
No related merge requests found
...@@ -442,22 +442,24 @@ class QuantificationManager[T](encoder: TemplateEncoder[T]) extends LambdaManage ...@@ -442,22 +442,24 @@ class QuantificationManager[T](encoder: TemplateEncoder[T]) extends LambdaManage
val lambdaSubstMap = lambdas map (lambda => lambda.ids._2 -> encoder.encodeId(lambda.ids._1)) val lambdaSubstMap = lambdas map (lambda => lambda.ids._2 -> encoder.encodeId(lambda.ids._1))
val substMap = subst.mapValues(Matcher.argValue) ++ baseSubstMap ++ lambdaSubstMap ++ instanceSubst(enablers) val substMap = subst.mapValues(Matcher.argValue) ++ baseSubstMap ++ lambdaSubstMap ++ instanceSubst(enablers)
instantiation ++= Template.instantiate(encoder, QuantificationManager.this, if (!skip(substMap)) {
clauses, blockers, applications, Seq.empty, Map.empty[T, Set[Matcher[T]]], lambdas, substMap) instantiation ++= Template.instantiate(encoder, QuantificationManager.this,
clauses, blockers, applications, Seq.empty, Map.empty[T, Set[Matcher[T]]], lambdas, substMap)
val msubst = subst.collect { case (c, Right(m)) => c -> m }
val substituter = encoder.substitute(substMap) val msubst = subst.collect { case (c, Right(m)) => c -> m }
val substituter = encoder.substitute(substMap)
for ((b,ms) <- allMatchers; m <- ms) {
val sb = enablers ++ (if (b == start) Set.empty else Set(substituter(b))) for ((b,ms) <- allMatchers; m <- ms) {
val sm = m.substitute(substituter, matcherSubst = msubst) val sb = enablers ++ (if (b == start) Set.empty else Set(substituter(b)))
val sm = m.substitute(substituter, matcherSubst = msubst)
if (matchers(m)) {
handled += sb -> sm if (matchers(m)) {
} else if (transMatchers(m) && isStrict) { handled += sb -> sm
instantiation ++= instCtx.instantiate(sb, sm)(quantifications.toSeq : _*) } else if (transMatchers(m) && isStrict) {
} else { instantiation ++= instCtx.instantiate(sb, sm)(quantifications.toSeq : _*)
ignored += sb -> sm } else {
ignored += sb -> sm
}
} }
} }
} }
...@@ -466,6 +468,8 @@ class QuantificationManager[T](encoder: TemplateEncoder[T]) extends LambdaManage ...@@ -466,6 +468,8 @@ class QuantificationManager[T](encoder: TemplateEncoder[T]) extends LambdaManage
} }
protected def instanceSubst(enablers: Set[T]): Map[T, T] protected def instanceSubst(enablers: Set[T]): Map[T, T]
protected def skip(subst: Map[T, T]): Boolean = false
} }
private class Quantification ( private class Quantification (
...@@ -515,7 +519,7 @@ class QuantificationManager[T](encoder: TemplateEncoder[T]) extends LambdaManage ...@@ -515,7 +519,7 @@ class QuantificationManager[T](encoder: TemplateEncoder[T]) extends LambdaManage
} }
} }
private class Axiom ( private class LambdaAxiom (
val start: T, val start: T,
val blocker: T, val blocker: T,
val guardVar: T, val guardVar: T,
...@@ -536,6 +540,13 @@ class QuantificationManager[T](encoder: TemplateEncoder[T]) extends LambdaManage ...@@ -536,6 +540,13 @@ class QuantificationManager[T](encoder: TemplateEncoder[T]) extends LambdaManage
val guardT = if (optEnabler.isDefined) encoder.mkAnd(start, optEnabler.get) else start val guardT = if (optEnabler.isDefined) encoder.mkAnd(start, optEnabler.get) else start
Map(guardVar -> guardT, blocker -> newBlocker) Map(guardVar -> guardT, blocker -> newBlocker)
} }
override protected def skip(subst: Map[T, T]): Boolean = {
val substituter = encoder.substitute(subst)
allMatchers.forall { case (b, ms) =>
ms.forall(m => matchers(m) || instCtx(Set(substituter(b)) -> m.substitute(substituter)))
}
}
} }
private def extractQuorums( private def extractQuorums(
...@@ -630,7 +641,7 @@ class QuantificationManager[T](encoder: TemplateEncoder[T]) extends LambdaManage ...@@ -630,7 +641,7 @@ class QuantificationManager[T](encoder: TemplateEncoder[T]) extends LambdaManage
var instantiation = Instantiation.empty[T] var instantiation = Instantiation.empty[T]
for (matchers <- matchQuorums) { for (matchers <- matchQuorums) {
val axiom = new Axiom(start, blocker, guardVar, quantified, val axiom = new LambdaAxiom(start, blocker, guardVar, quantified,
matchers, allMatchers, condVars, exprVars, condTree, matchers, allMatchers, condVars, exprVars, condTree,
clauses, blockers, applications, lambdas clauses, blockers, applications, lambdas
) )
......
...@@ -311,10 +311,64 @@ class TemplateGenerator[T](val encoder: TemplateEncoder[T], ...@@ -311,10 +311,64 @@ class TemplateGenerator[T](val encoder: TemplateEncoder[T],
} }
case a @ And(parts) => case a @ And(parts) =>
liftToIfExpr(pathVar, parts, andJoin, (a,b) => IfExpr(a, b, BooleanLiteral(false))) val partitions = groupWhile(parts)(!requireDecomposition(_))
partitions.map(andJoin) match {
case Seq(e) => e
case seq =>
val newExpr : Identifier = FreshIdentifier("e", BooleanType, true)
storeExpr(newExpr)
def recAnd(pathVar: Identifier, partitions: Seq[Expr]): Unit = partitions match {
case x :: Nil if !requireDecomposition(x) =>
storeGuarded(pathVar, Equals(Variable(newExpr), x))
case x :: xs =>
val newBool : Identifier = FreshIdentifier("b", BooleanType, true)
storeCond(pathVar, newBool)
val xrec = rec(pathVar, x)
storeGuarded(pathVar, Equals(Variable(newBool), xrec))
storeGuarded(pathVar, Implies(Not(Variable(newBool)), Not(Variable(newExpr))))
recAnd(newBool, xs)
case Nil =>
storeGuarded(pathVar, Variable(newExpr))
}
recAnd(pathVar, seq)
Variable(newExpr)
}
case o @ Or(parts) => case o @ Or(parts) =>
liftToIfExpr(pathVar, parts, orJoin, (a,b) => IfExpr(a, BooleanLiteral(true), b)) val partitions = groupWhile(parts)(!requireDecomposition(_))
partitions.map(orJoin) match {
case Seq(e) => e
case seq =>
val newExpr : Identifier = FreshIdentifier("e", BooleanType, true)
storeExpr(newExpr)
def recOr(pathVar: Identifier, partitions: Seq[Expr]): Unit = partitions match {
case x :: Nil if !requireDecomposition(x) =>
storeGuarded(pathVar, Equals(Variable(newExpr), x))
case x :: xs =>
val newBool : Identifier = FreshIdentifier("b", BooleanType, true)
storeCond(pathVar, newBool)
val xrec = rec(pathVar, x)
storeGuarded(pathVar, Equals(Not(Variable(newBool)), xrec))
storeGuarded(pathVar, Implies(Not(Variable(newBool)), Variable(newExpr)))
recOr(newBool, xs)
case Nil =>
storeGuarded(pathVar, Not(Variable(newExpr)))
}
recOr(pathVar, seq)
Variable(newExpr)
}
case i @ IfExpr(cond, thenn, elze) => { case i @ IfExpr(cond, thenn, elze) => {
if(!requireDecomposition(i)) { if(!requireDecomposition(i)) {
......
...@@ -67,7 +67,7 @@ object PropositionalLogic { ...@@ -67,7 +67,7 @@ object PropositionalLogic {
// nnf(simplify(f)) == simplify(nnf(f)) // nnf(simplify(f)) == simplify(nnf(f))
// }.holds // }.holds
//@induct @induct
def simplifyBreaksNNF(f: Formula) : Boolean = { def simplifyBreaksNNF(f: Formula) : Boolean = {
require(isNNF(f)) require(isNNF(f))
isNNF(simplify(f)) isNNF(simplify(f))
......
...@@ -66,11 +66,6 @@ class PureScalaValidSuiteCVC4 extends PureScalaValidSuite { ...@@ -66,11 +66,6 @@ class PureScalaValidSuiteCVC4 extends PureScalaValidSuite {
} }
class PureScalaInvalidSuite extends PureScalaVerificationSuite { class PureScalaInvalidSuite extends PureScalaVerificationSuite {
override val ignored = Seq(
"verification/purescala/invalid/PropositionalLogic.scala",
"verification/purescala/invalid/InductiveQuantification.scala"
)
override def testAll() = testInvalid() override def testAll() = testInvalid()
val optionVariants = opts val optionVariants = opts
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment