Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invariant Solver #214

Merged
merged 50 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
b488798
New Simple Horn Solver reimplementation
sankalpgambhir Apr 4, 2024
9685d3e
Add eldarica and z3 relative paths
sankalpgambhir Apr 5, 2024
b86d5d0
Fix multiple symbol declaration
sankalpgambhir Apr 5, 2024
3ace46d
Rewrite Constraint Processing
sankalpgambhir Apr 5, 2024
875a65d
Ignore semanticdb
sankalpgambhir Apr 5, 2024
1a1332d
Regenerate TIP files
sankalpgambhir Apr 5, 2024
fd71988
Reseal Symbols
sankalpgambhir Apr 5, 2024
d7f8b2c
Better Instructions
sankalpgambhir Apr 5, 2024
9003408
Package compiled eldarica
sankalpgambhir Apr 5, 2024
3858f70
Redo many parts; more explicit constraint generation
sankalpgambhir May 15, 2024
61f9d1d
Make Horn solvers available via SolverFactory
sankalpgambhir May 15, 2024
e87d0af
Differentiate predicates from HOF in SMTLibTarget
sankalpgambhir May 15, 2024
bdcc4d1
Add Invariant solvers to factory
sankalpgambhir Aug 7, 2024
fabe256
Cleanup SimpleSolver
sankalpgambhir Aug 7, 2024
3a8bb23
Add Invariant Solver
sankalpgambhir Aug 7, 2024
78e7455
Remove spurious prints
sankalpgambhir Aug 7, 2024
5066da4
Change constraint accumulation format
sankalpgambhir Aug 7, 2024
831eebf
Make predicate defs not hide guards
sankalpgambhir Aug 7, 2024
010bfeb
Accumulate top-level assumes as assertions
sankalpgambhir Aug 7, 2024
d3149cc
More precise handling of disjunction branching
sankalpgambhir Aug 7, 2024
5cce5f2
Generate goal clauses from top-level assertions
sankalpgambhir Aug 7, 2024
6fa29af
Change check to match new assertion handling
sankalpgambhir Aug 7, 2024
2494c13
Clarify unreachable pattern match error
sankalpgambhir Aug 7, 2024
1297820
Rewrite constraint generation to aggressively separate and simplify e…
sankalpgambhir Aug 13, 2024
04d60e6
Remove debug prints
sankalpgambhir Aug 13, 2024
bd28265
Extend support for z3 SMTLIB models
sankalpgambhir Aug 13, 2024
c86347d
Remove SimpleHornSolver
sankalpgambhir Aug 13, 2024
d0babac
Loosen treatment of guards and nested assertions
sankalpgambhir Aug 13, 2024
e2257bf
More precise transitive guard collection for predicate types
sankalpgambhir Aug 13, 2024
1939385
Explicit node naming
sankalpgambhir Aug 13, 2024
9d1eb30
Vacuity checking for models
sankalpgambhir Aug 13, 2024
f23da09
Model extraction for predicates
sankalpgambhir Sep 12, 2024
9aa5699
Fix underlying interrupts
sankalpgambhir Sep 12, 2024
7eeec87
Check that guards are computed transitively
sankalpgambhir Sep 12, 2024
5e181a7
Assure canonicalization of operator arguments
sankalpgambhir Sep 12, 2024
96723dd
Mkae HOF internals private
sankalpgambhir Sep 12, 2024
ee68e5f
Disable aggressive model printing
sankalpgambhir Sep 12, 2024
aff51ea
Remove non-vacuity checks for models
sankalpgambhir Sep 12, 2024
8f81773
Redo uuverifiers dependencies
sankalpgambhir Sep 12, 2024
8db52e3
Removed dangling inductive examples
sankalpgambhir Sep 12, 2024
8e7808f
Revert require message change
sankalpgambhir Sep 12, 2024
6eee2dd
Revert README about old examples
sankalpgambhir Sep 12, 2024
9bd8aa6
Remove eldarica wrapper
sankalpgambhir Sep 12, 2024
6b862c5
Rename uuverifiers resolver
sankalpgambhir Sep 12, 2024
96a02ab
Fix solver names
sankalpgambhir Sep 17, 2024
7e1e98c
Remvoe accidental result-flipping in previous change
sankalpgambhir Sep 17, 2024
d4bb72a
Remove unused method that accesses interpreter internals
sankalpgambhir Sep 17, 2024
9bf9546
Add new Eldarica interpreter (without IPC)
sankalpgambhir Sep 17, 2024
b63317e
Only return a model if the config requests it
sankalpgambhir Sep 24, 2024
51404e6
Add basic tests
sankalpgambhir Sep 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,5 @@ out-classes
project/.bloop/
project/metals.sbt
project/project/

*.semanticdb
17 changes: 11 additions & 6 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,21 @@ Compile / unmanagedJars += {
resolvers ++= Seq(
"Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots",
"Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases",
("uuverifiers" at "http://logicrunch.research.it.uu.se/maven").withAllowInsecureProtocol(true)
"uuverifiers" at "https://eldarica.org/maven"
)

libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.2.9" % "test;it",
"org.apache.commons" % "commons-lang3" % "3.4",
("org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2").cross(CrossVersion.for3Use2_13)
("uuverifiers" %% "eldarica" % "nightly-SNAPSHOT").cross(CrossVersion.for3Use2_13),
("uuverifiers" %% "princess" % "nightly-SNAPSHOT").cross(CrossVersion.for3Use2_13),
"org.scala-lang.modules" %% "scala-parser-combinators" % "2.3.0"
)

excludeDependencies ++= Seq(
"org.scala-lang.modules" % "scala-parser-combinators_2.13",
"org.scala-lang.modules" % "scala-xml_2.13",
"org.scalactic" % "scalactic_2.13",
)

lazy val nTestParallelism = {
Expand All @@ -60,9 +68,6 @@ def ghProject(repo: String, version: String) = RootProject(uri(s"${repo}#${versi
// lazy val smtlib = RootProject(file("../scala-smtlib")) // If you have a local copy of Scala-SMTLIB and would like to do some changes
lazy val smtlib = ghProject("https://github.com/epfl-lara/scala-smtlib.git", "51a44878858b427f1a4e5a5eb01d8f796898d812")

// lazy val princess = RootProject(file("../princess")) // If you have a local copy of Princess and would like to do some changes
lazy val princess = ghProject("https://github.com/uuverifiers/princess.git", "93cbff11d7b02903e532c7b64207bc12f19b79c7")

lazy val scriptName = settingKey[String]("Name of the generated 'inox' script")

scriptName := "inox"
Expand Down Expand Up @@ -153,7 +158,7 @@ lazy val root = (project in file("."))
)) : _*)
.settings(compile := ((Compile / compile) dependsOn script).value)
.settings(Compile / packageDoc / mappings := Seq())
.dependsOn(smtlib, princess)
.dependsOn(smtlib)

Global / concurrentRestrictions := Seq(
Tags.limit(Tags.Test, nTestParallelism)
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/inox/ast/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ trait TypeOps {
def greatestLowerBound(tps: Seq[Type]): Type =
if (tps.isEmpty) Untyped else tps.reduceLeft(greatestLowerBound)

def isSubtypeOf(t1: Type, t2: Type): Boolean = t1.getType == t2.getType
def isSubtypeOf(t1: Type, t2: Type): Boolean =
t1.getType == Untyped || t2.getType == Untyped || t1.getType == t2.getType

private type Instantiation = Map[TypeParameter, Type]
def instantiation(from: Type, to: Type): Option[Instantiation] = {
Expand Down
102 changes: 101 additions & 1 deletion src/main/scala/inox/solvers/SolverFactory.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package solvers

import transformers._
import inox.solvers.evaluating.EvaluatingSolver
import inox.solvers.invariant.AbstractInvariantSolver
import inox.solvers.invariant.InvariantSolver

trait SolverFactory {
val program: Program
Expand Down Expand Up @@ -80,17 +82,21 @@ object SolverFactory {
"smt-z3-opt" -> "Z3 optimizer through SMT-LIB",
"smt-z3:<exec>" -> "Z3 through SMT-LIB with custom executable name",
"princess" -> "Princess with inox unrolling",
"eval" -> "Internal evaluator to discharge ground assertions"
"eval" -> "Internal evaluator to discharge ground assertions",
"inv-z3" -> "Horn solver using Z3 / Spacer",
"inv-eld" -> "Horn solver using Eldarica"
)

private val fallbacks = Map(
"nativez3" -> (() => hasNativeZ3, Seq("smt-z3", "smt-cvc4", "smt-cvc5", "princess"), "Z3 native interface"),
"nativez3-opt" -> (() => hasNativeZ3, Seq("smt-z3-opt"), "Z3 native interface"),
"unrollz3" -> (() => hasNativeZ3, Seq("smt-z3", "smt-cvc4", "smt-cvc5", "princess"), "Z3 native interface"),
"inv-z3" -> (() => hasZ3, Seq("smt-z3", "smt-cvc4", "smt-cvc5", "princess"), "Z3 native interface"),
"smt-cvc4" -> (() => hasCVC4, Seq("nativez3", "smt-z3", "princess"), "'cvc4' binary"),
"smt-cvc5" -> (() => hasCVC5, Seq("nativez3", "smt-z3", "princess"), "'cvc5' binary"),
"smt-z3" -> (() => hasZ3, Seq("nativez3", "smt-cvc4", "smt-cvc5", "princess"), "'z3' binary"),
"smt-z3-opt" -> (() => hasZ3, Seq("nativez3-opt"), "'z3' binary"),
"inv-eld" -> (() => true, Seq(), "Eldarica solver"),
"princess" -> (() => true, Seq(), "Princess solver"),
"eval" -> (() => true, Seq(), "Internal evaluator")
)
Expand Down Expand Up @@ -257,6 +263,100 @@ object SolverFactory {
() => new SMTZ3OptImpl(p)
})

case "inv-z3" => create(p)(finalName, {
val emptyEnc = ProgramEncoder.empty(enc.targetProgram)
val chooses = ChooseEncoder(enc.targetProgram)(emptyEnc)
class SMTZ3Impl(override val program: enc.targetProgram.type)
extends AbstractInvariantSolver (program, ctx)(program)(emptyEnc)(emptyEnc)(using program.getSemantics, emptyEnc.targetProgram.getSemantics)
with InvariantSolver
with TimeoutSolver
with tip.TipDebugger {

override val name = "inv-z3"

class Underlying(override val program: targetProgram.type)
extends smtlib.SMTLIBSolver(program, context)
with smtlib.Z3Solver {
override def targetName = "z3"
import _root_.smtlib.trees.Terms
import _root_.smtlib.trees.CommandsResponses._
import _root_.smtlib.trees.Commands._
import _root_.smtlib.Interpreter
import _root_.smtlib.printer.Printer
import _root_.smtlib.printer.RecursivePrinter
import java.io.BufferedReader
import _root_.smtlib.interpreters.ProcessInterpreter
import _root_.smtlib.parser.Parser
import _root_.smtlib.extensions.tip.Lexer

class HornZ3Interpreter(executable: String,
args: Array[String],
printer: Printer = RecursivePrinter,
parserCtor: BufferedReader => Parser = out => new Parser(new Lexer(out)))
extends ProcessInterpreter (executable, args, printer, parserCtor):
printer.printCommand(SetOption(PrintSuccess(true)), in)
in.write("\n")
in.flush()
parser.parseGenResponse
in.write("(set-logic HORN)\n")
in.flush()
parser.parseGenResponse

override def eval(cmd: Terms.SExpr): Terms.SExpr =
super.eval(cmd)

override protected val interpreter = {
val opts = interpreterOpts
// reporter.debug("Invoking solver "+targetName+" with "+opts.mkString(" "))
new HornZ3Interpreter(targetName, opts.toArray, parserCtor = out => new Z3Parser(new Lexer(out)))
}
}

override protected val underlyingHorn = Underlying(targetProgram)

// encoder is from TipDebugger and enc from AbstractUnrollingSolver
override protected val encoder = emptyEnc
}

class EncodedImpl(program: p.type, enc: transformers.ProgramTransformer {
val sourceProgram: program.type
val targetProgram: Program { val trees: inox.trees.type }
}, underlying: Solver {val program: enc.targetProgram.type})
extends EncodingSolver(program, enc, underlying) with TimeoutSolver

() => new EncodedImpl(p, enc, SMTZ3Impl(enc.targetProgram))
})

case "inv-eld" => create(p)(finalName, {
val emptyEnc = ProgramEncoder.empty(enc.targetProgram)
val chooses = ChooseEncoder(enc.targetProgram)(emptyEnc)
class SMTEldaricaImpl(override val program: enc.targetProgram.type)
extends AbstractInvariantSolver (program, ctx)(program)(emptyEnc)(emptyEnc)(using program.getSemantics, emptyEnc.targetProgram.getSemantics)
with InvariantSolver
with TimeoutSolver
with tip.TipDebugger {

override val name = "inv-eld"

class Underlying(override val program: targetProgram.type)
extends smtlib.SMTLIBSolver(program, context)
with smtlib.EldaricaSolver

override protected val underlyingHorn = Underlying(targetProgram)

// encoder is from TipDebugger and enc from AbstractUnrollingSolver
override protected val encoder = emptyEnc
}

class EncodedImpl(program: p.type, enc: transformers.ProgramTransformer {
val sourceProgram: program.type
val targetProgram: Program { val trees: inox.trees.type }
}, underlying: Solver {val program: enc.targetProgram.type})
extends EncodingSolver(program, enc, underlying) with TimeoutSolver

() => new EncodedImpl(p, enc, SMTEldaricaImpl(enc.targetProgram))
})

case _ if finalName == "smt-z3" || finalName.startsWith("smt-z3:") => create(p)(finalName, {
class SMTZ3Impl(override val program: p.type)
(override val enc: transformers.ProgramTransformer {
Expand Down
Loading
Loading