Skip to content
This repository was archived by the owner on Nov 22, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
7dc7f47
fixes filtering of failures by taking error transformers into account
ArquintL Dec 13, 2021
e179c80
Merges branch 'master' into 'failure-filtering-fix'
ArquintL Dec 13, 2021
160951d
implements CR suggestions by Malte
ArquintL Dec 16, 2021
22551b4
Merge pull request #584 from viperproject/failure-filtering-fix
ArquintL Dec 16, 2021
6049460
adapts Silicon to latest changes in Silver regarding the counterexamp…
ArquintL Jan 5, 2022
937caa5
Remove quotes around Z3 arguments
fpoli Jan 19, 2022
7aa97f1
Report quantifier instantiations
fpoli Jan 18, 2022
0f24cdd
Merge pull request #587 from viperproject/qi_profile
fpoli Jan 20, 2022
45dba73
Fix silicon.bat script
fpoli Jan 25, 2022
77845a2
Injectivity check at inhale by default
tdardinier Jan 26, 2022
21fd600
Removed heuristics (from ECOOP magic wand paper)
mschwerhoff Jan 28, 2022
f963fae
Merge pull request #589 from viperproject/remove-wand-heuristics
mschwerhoff Jan 28, 2022
014312d
Removed a no longer existing test directory from the test driver
mschwerhoff Feb 4, 2022
479d7c2
Rollback a problematic change that cause #592.
vakaras Feb 4, 2022
1a920cc
Merge pull request #593 from viperproject/fix-592
mschwerhoff Feb 6, 2022
0d4130e
Injectivity checks updated tests
tdardinier Feb 8, 2022
525434d
fix typo in command-line option
Aurel300 Feb 8, 2022
ae2c15f
Enable bors.
vakaras Feb 8, 2022
c2cf02e
Merge #596
bors[bot] Feb 8, 2022
2d5375e
Resolved Silicon issue #595
Feb 8, 2022
a701b80
Merge #597
bors[bot] Feb 8, 2022
cd20cf0
Merge #598
bors[bot] Feb 11, 2022
4ca96a4
Weakened a sequence axiom trigger to resolve #601
Mar 8, 2022
43ea415
Merge pull request #588 from viperproject/remove-quotes
fpoli Mar 25, 2022
c8d10c2
Silver as a Submodule (#605)
JonasAlaif Mar 28, 2022
4a89b65
Update silver submodule
Mar 28, 2022
3fc625d
Update silver submodule
Mar 28, 2022
ab076ed
Update silver submodule
Mar 28, 2022
9cc21b5
Update silver submodule
Mar 29, 2022
47e74c6
Update Build Instructions
JonasAlaif Mar 29, 2022
35d8bd3
Added support for perm-perm-multiplication
marcoeilers Apr 3, 2022
b9ffda6
Update silver submodule
Apr 3, 2022
fe68490
Merge pull request #608 from viperproject/perm_multiplication
marcoeilers Apr 3, 2022
d51e17b
Update silver submodule
Apr 3, 2022
0ec573c
Update silver submodule
Apr 3, 2022
6a927a9
Update silver submodule
Apr 3, 2022
1f66b70
Update silver submodule
Apr 6, 2022
8df301a
Requiring more complete exhale option for counterexamples (otherwise …
marcoeilers Apr 6, 2022
d71741f
Changes for perm perm division that I forgot to commit yesterday
marcoeilers Apr 6, 2022
5e674e9
Removed dead code
mschwerhoff Apr 10, 2022
7194b96
IntelliJ suggestions
mschwerhoff Apr 10, 2022
748faf1
Update silver submodule
Apr 10, 2022
b7f61e7
Merge branch 'cvc5' into master
lfwa Apr 22, 2022
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
11 changes: 4 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

name: ci

on: [push, pull_request]
on: [push, pull_request, workflow_dispatch]

env:
RELEASE_DIR: tmp_release
Expand All @@ -25,13 +25,8 @@ jobs:
# Checkout Silicon (note: all checkouts delete the contents of their working directory)
- name: Checkout Silicon
uses: actions/checkout@v2

# Checkout Viper dependencies (just Silver)
- name: Checkout Silver
uses: actions/checkout@v2
with:
repository: viperproject/silver
path: silver
submodules: true

# Query versions, and other details that may help with reconstructing a built.
# Results are displayed on stdio, and written to buildinfo.log
Expand Down Expand Up @@ -91,6 +86,8 @@ jobs:
# Checkout Silicon (deletes content of working directory)
- name: Checkout Silicon
uses: actions/checkout@v2
with:
submodules: true

- name: Download artifacts from job test-and-assemble
uses: actions/download-artifact@v2
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ utils/tidy_smtlib/tidy_smtlib.jar
utils/scripts/tidy_smtlib.jar
silicon_classpath.txt
lib/
silver
src/test/resources/symbExLogTests/*.alog
.DS_Store
viper_tutorial_examples
.bsp/
.bloop/
.metals/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "silver"]
path = silver
url = https://github.com/viperproject/silver.git
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,22 @@ method main() {

# Build Instructions

> See [the documentation wiki](https://github.com/viperproject/documentation/wiki) for instructions on how to try out or install the Viper tools.

* You need recent installations of
1. the [sbt build tool](https://www.scala-sbt.org/)
2. the [Z3 SMT solver](https://github.com/Z3Prover/z3/releases)
3. the [cvc5 SMT solver](https://github.com/cvc5/cvc5/releases)
* Clone [Silver](https://github.com/viperproject/silver), e.g. into `~/silver`
* Clone Silicon (this repository), e.g. into `~/silicon`
* From within the directory where you installed Silicon, create a symbolic link to the directory where you installed Silver. E.g. there should be a symbolic link from `~/silicon/silver` to `~/silver`. Alternatively, directly clone Silver into, e.g. `~/silicon/silver`.
* Open a console, change directory to `~/silicon`
* Compile by running `sbt compile`, or run all tests via `sbt test`
* We recommend IDEA IntelliJ for Scala development, but any IDE that supports sbt will do
* Clone this repository *recursively* by running:
`git clone --recursive https://github.com/viperproject/silicon`

And then, from the cloned directory, with the `Z3_EXE` environment variable set appropriately;
* Compile and run with:
`sbt "run [options] <path to Viper file>"`
Or run all tests via `sbt test`
* Alternatively, for a faster startup without compilation each time, build a `.jar` file:
`sbt assembly`
And then run with:
`java -jar ./target/scala-*/silicon.jar [options] <path to Viper file>`

> We recommend IDEA IntelliJ for Scala development, but any IDE that supports sbt will do
1 change: 1 addition & 0 deletions annotation/Terms.example.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1971,6 +1971,7 @@ object utils {
case PermTimes(t0, t1) => consumeExactRead(t0, constrainableARPs) && consumeExactRead(t1, constrainableARPs)
case IntPermTimes(_, t1) => consumeExactRead(t1, constrainableARPs)
case PermIntDiv(t0, _) => consumeExactRead(t0, constrainableARPs)
case PermPermDiv(t0, t1) => consumeExactRead(t0, constrainableARPs) && consumeExactRead(t1, constrainableARPs)
case PermMin(t0 ,t1) => consumeExactRead(t0, constrainableARPs) || consumeExactRead(t1, constrainableARPs)
case Ite(_, t0, t1) => consumeExactRead(t0, constrainableARPs) || consumeExactRead(t1, constrainableARPs)
case _ => true
Expand Down
1 change: 1 addition & 0 deletions bors.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
status = ["test-and-assemble"]
12 changes: 4 additions & 8 deletions silicon.bat
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set CURR_DIR=%cd%
set BASE_DIR=%~dp0

:: switch to repository root to check for classpath file and possibly call sbt.
cd %BASE_DIR%
cd "%BASE_DIR%"

:: Only call sbt if the classpath file is missing.
if not exist silicon_classpath.txt (
Expand All @@ -22,12 +22,8 @@ if not exist silicon_classpath.txt (
for /f "delims=" %%x in (silicon_classpath.txt) do set CP=%%x

:: switch back to original directory
cd %CURR_DIR%
cd "%CURR_DIR%"

set JAVA_EXE=java
set JVM_OPTS=-Dlogback.configurationFile="%BASE_DIR%\src\main\resources\logback.xml" -Xss16m -Dfile.encoding=UTF-8
set SILICON_MAIN=viper.silicon.SiliconRunner
set FWD_ARGS= %*
set CMD=%JAVA_EXE% %JVM_OPTS% -cp "%CP%" %SILICON_MAIN% %FWD_ARGS%
set JVM_OPTS=-Xss16m -Dlogback.configurationFile="%BASE_DIR%\src\main\resources\logback.xml" -Dfile.encoding=UTF-8

call %CMD%
call java %JVM_OPTS% -cp "%CP%" viper.silicon.SiliconRunner %*
10 changes: 4 additions & 6 deletions silicon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@

set -e

set -e

BASEDIR="$(realpath `dirname $0`)"
BASEDIR="$(realpath "$(dirname "$0")")"

CP_FILE="$BASEDIR/silicon_classpath.txt"

if [ ! -f $CP_FILE ]; then
(cd $BASEDIR; sbt "export runtime:dependencyClasspath" | tail -n1 > $CP_FILE)
if [ ! -f "$CP_FILE" ]; then
(cd "$BASEDIR"; sbt "export runtime:dependencyClasspath" | tail -n1 > "$CP_FILE")
fi

java -Xss30M -Dlogback.configurationFile="$BASEDIR/src/main/resources/logback.xml" -cp "`cat $CP_FILE`" viper.silicon.SiliconRunner $@
exec java -Xss30M -Dlogback.configurationFile="$BASEDIR/src/main/resources/logback.xml" -cp "$(cat "$CP_FILE")" viper.silicon.SiliconRunner "$@"
1 change: 1 addition & 0 deletions silver
Submodule silver added at ec231f
4 changes: 3 additions & 1 deletion src/main/resources/dafny_axioms/sequences.vpr
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ domain $Seq[E] {
}

axiom seq_index_over_singleton {
forall e: E :: {Seq_index(Seq_singleton(e), 0)}
forall e: E ::
// {Seq_index(Seq_singleton(e), 0)}
{Seq_singleton(e)} // [2022-03-08 Malte] Weaker trigger to resolve Silicon issue #601
Seq_index(Seq_singleton(e), 0) == e
}

Expand Down
31 changes: 13 additions & 18 deletions src/main/scala/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,11 @@ class Config(args: Seq[String]) extends SilFrontendConfig(args, "Silicon") {
// val argType: ArgType.V = org.rogach.scallop.ArgType.LIST
// }

private val forwardArgumentsConverter: ValueConverter[String] = new ValueConverter[String] {
def parse(s: List[(String, List[String])]): Either[String, Option[String]] = s match {
case (_, str :: Nil) :: Nil if str.head == '"' && str.last == '"' => Right(Some(str.substring(1, str.length - 1)))
case Nil => Right(None)
case _ => Left(s"unexpected arguments")
}

val argType: ArgType.V = org.rogach.scallop.ArgType.LIST
}

private val smtlibOptionsConverter: ValueConverter[Map[String, String]] = new ValueConverter[Map[String, String]] {
def parse(s: List[(String, List[String])]): Either[String, Option[Map[String, String]]] = s match {
case (_, str :: Nil) :: Nil if str.head == '"' && str.last == '"' =>
case (_, str :: Nil) :: Nil =>
val config = toMap(
str.substring(1, str.length - 1) /* Drop leading and trailing quotation mark */
.split(' ') /* Separate individual key=value pairs */
str.split(' ') /* Separate individual key=value pairs */
.map(_.trim)
.filter(_.nonEmpty)
.map(_.split('=')) /* Split key=value pairs */
Expand Down Expand Up @@ -503,18 +492,18 @@ class Config(args: Seq[String]) extends SilFrontendConfig(args, "Silicon") {

private val rawProverArgs: ScallopOption[String] = opt[String]("proverArgs",
descr = ( "Command-line arguments which should be forwarded to the prover. "
+ "The expected format is \"<opt> <opt> ... <opt>\", including the quotation marks."),
+ "The expected format is \"<opt> <opt> ... <opt>\", excluding the quotation marks."),
default = None,
noshort = true
)(forwardArgumentsConverter)
)

// DEPRECATED and replaced by proverArgs
// but continues to work for now for backwards compatibility.
private val rawZ3Args: ScallopOption[String] = opt[String]("z3Args",
descr = ( "Warning: This option is deprecated due to standardization in option naming."
+ " Please use 'proverArgs' instead... "
+ "Command-line arguments which should be forwarded to Z3. "
+ "The expected format is \"<opt> <opt> ... <opt>\", including the quotation marks."),
+ "The expected format is \"<opt> <opt> ... <opt>\", excluding the quotation marks."),
default = None,
noshort = true
)(forwardArgumentsConverter)
Expand All @@ -540,7 +529,7 @@ class Config(args: Seq[String]) extends SilFrontendConfig(args, "Silicon") {
+ " Please use 'proverConfigArgs' instead... "
+ "Configuration options which should be forwarded to Z3. "
+ "The expected format is \"<key>=<val> <key>=<val> ... <key>=<val>\", "
+ "including the quotation marks. "
+ "excluding the quotation marks. "
+ "The configuration options given here will override those from Silicon's Z3 preamble."),
default = Some(Map()),
noshort = true
Expand Down Expand Up @@ -678,7 +667,7 @@ class Config(args: Seq[String]) extends SilFrontendConfig(args, "Silicon") {
default = Some(false),
noshort = true
)
val enableBranchconditionReporting: ScallopOption[Boolean] = opt[Boolean]("enableBranchconditionReorting",
val enableBranchconditionReporting: ScallopOption[Boolean] = opt[Boolean]("enableBranchconditionReporting",
descr = "Report branch conditions (can be useful for assertions that fail on multiple branches)",
default = Some(false),
noshort = true
Expand Down Expand Up @@ -765,6 +754,12 @@ class Config(args: Seq[String]) extends SilFrontendConfig(args, "Silicon") {
case other =>
sys.error(s"Unexpected combination: $other")
}

validateOpt(counterexample, enableMoreCompleteExhale) {
case (Some(_), Some(false)) => Left( s"Option ${counterexample.name} requires setting "
+ s"flag ${enableMoreCompleteExhale.name}")
case _ => Right(())
}

validateFileOpt(logConfig)
validateFileOpt(setAxiomatizationFile)
Expand Down
33 changes: 26 additions & 7 deletions src/main/scala/Silicon.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import org.slf4j.LoggerFactory
import viper.silver.ast
import viper.silver.frontend.{DefaultStates, SilFrontend}
import viper.silver.reporter._
import viper.silver.verifier.{Failure => SilFailure, Success => SilSuccess, TimeoutOccurred => SilTimeoutOccurred, VerificationResult => SilVerificationResult, Verifier => SilVerifier}
import viper.silver.verifier.{AbstractVerificationError => SilAbstractVerificationError, Failure => SilFailure, Success => SilSuccess, TimeoutOccurred => SilTimeoutOccurred, VerificationResult => SilVerificationResult, Verifier => SilVerifier}
import viper.silicon.interfaces.Failure
import viper.silicon.logger.SymbExLogger
import viper.silicon.reporting.condenseToViperResult
Expand Down Expand Up @@ -253,16 +253,13 @@ class Silicon(val reporter: Reporter, private var debugInfo: Seq[(String, Any)]
* of all failures that report the same error (but on different branches, with different CounterExample)
* and put those into one failure */
if (config.enableBranchconditionReporting())
allResults.groupBy(_.message.readableMessage(withId = true, withPosition = true)).map{case (_: String, fs:List[Failure]) =>
allResults.groupBy(failureFilterAndGroupingCriterion).map{case (_: String, fs:List[Failure]) =>
fs.head.message.failureContexts = fs.flatMap(_.message.failureContexts)
Failure(fs.head.message)
}.toList
else allResults.distinctBy(f => f.message.readableMessage(withId = true, withPosition = true))
})
.sortBy(_.message.pos match { /* Order failures according to source position */
case pos: ast.HasLineColumn => (pos.line, pos.column)
case _ => (-1, -1)
else allResults.distinctBy(failureFilterAndGroupingCriterion)
})
.sortBy(failureSortingCriterion)

// if (config.showStatistics.isDefined) {
// val proverStats = verifier.decider.statistics()
Expand Down Expand Up @@ -293,6 +290,28 @@ class Silicon(val reporter: Reporter, private var debugInfo: Seq[(String, Any)]
failures
}

private def failureFilterAndGroupingCriterion(f: Failure): String = {
// apply transformers if available:
val transformedError = f.message match {
case e: SilAbstractVerificationError => e.transformedError()
case e => e
}
// create a string that identifies the given failure:
transformedError.readableMessage(withId = true, withPosition = true)
}

private def failureSortingCriterion(f: Failure): (Int, Int) = {
// apply transformers if available:
val transformedError = f.message match {
case e: SilAbstractVerificationError => e.transformedError()
case e => e
}
transformedError.pos match { /* Order failures according to source position */
case pos: ast.HasLineColumn => (pos.line, pos.column)
case _ => (-1, -1)
}
}

private def logFailure(failure: Failure, log: String => Unit): Unit = { //TODO:J log context?
log("\n" + failure.message.readableMessage(withId = true, withPosition = true))
}
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/decider/TermToSMTLib2Converter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ class TermToSMTLib2Converter
case PermTimes(t0, t1) => renderBinaryOp("*", renderAsReal(t0), renderAsReal(t1))
case IntPermTimes(t0, t1) => renderBinaryOp("*", renderAsReal(t0), renderAsReal(t1))
case PermIntDiv(t0, t1) => renderBinaryOp("/", renderAsReal(t0), renderAsReal(t1))
case PermPermDiv(t0, t1) => renderBinaryOp("/", renderAsReal(t0), renderAsReal(t1))
case PermMin(t0, t1) => renderBinaryOp("$Perm.min", render(t0), render(t1))
case IsValidPermVar(v) => parens(text("$Perm.isValidVar") <+> render(v))
case IsReadPermVar(v, ub) => parens(text("$Perm.isReadVar") <+> render(v) <+> render(ub))
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/logger/writer/TermWriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ object TermWriter {

def toJSON(term: Term): JsValue = term match {

case b: BinaryOp[Term] => binary(b.op, toJSON(b.p0), toJSON(b.p1))
case u: UnaryOp[Term] => unary(u.op, toJSON(u.p))
case b: BinaryOp[Term@unchecked] => binary(b.op, toJSON(b.p0), toJSON(b.p1))
case u: UnaryOp[Term@unchecked] => unary(u.op, toJSON(u.p))

// TODO: do we need triggers and isGlobal?
case Quantification(quantifier, vars, body, _, name, _) =>
Expand Down
70 changes: 27 additions & 43 deletions src/main/scala/rules/ChunkSupporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ trait ChunkSupportRules extends SymbolicExecutionRules {
resource: ast.Resource,
args: Seq[Term],
ve: VerificationError,
v: Verifier,
description: String)
v: Verifier)
(Q: (State, Heap, Term, Verifier) => VerificationResult)
: VerificationResult

Expand Down Expand Up @@ -74,32 +73,33 @@ object chunkSupporter extends ChunkSupportRules {
(Q: (State, Heap, Term, Verifier) => VerificationResult)
: VerificationResult = {

heuristicsSupporter.tryOperation[Heap, Term](description)(s, h, v)((s1, h1, v1, QS) => {
consume(s1, h1, resource, args, perms, ve, v1)((s2, h2, optSnap, v2) =>
optSnap match {
case Some(snap) =>
QS(s2, h2, snap.convert(sorts.Snap), v2)
case None =>
/* Not having consumed anything could mean that we are in an infeasible
* branch, or that the permission amount to consume was zero.
* Returning a fresh snapshot in these cases should not lose any information.
*/
val fresh = v2.decider.fresh(sorts.Snap)
val s3 = s2.copy(functionRecorder = s2.functionRecorder.recordFreshSnapshot(fresh.applicable))
QS(s3, h2, fresh, v2)
})
})(Q)
consume2(s, h, resource, args, perms, ve, v)((s2, h2, optSnap, v2) =>
optSnap match {
case Some(snap) =>
Q(s2, h2, snap.convert(sorts.Snap), v2)
case None =>
/* Not having consumed anything could mean that we are in an infeasible
* branch, or that the permission amount to consume was zero.
*
* [MS 2022-01-28] Previously, a a fresh snapshot was retured, which also had to be
* registered with the function recorder. However, since nothing was consumed,
* returning the unit snapshot seems more appropriate.
*/
val fresh = v2.decider.fresh(sorts.Snap)
val s3 = s2.copy(functionRecorder = s2.functionRecorder.recordFreshSnapshot(fresh.applicable))
Q(s3, h2, fresh, v2)
})
}

private def consume(s: State,
h: Heap,
resource: ast.Resource,
args: Seq[Term],
perms: Term,
ve: VerificationError,
v: Verifier)
(Q: (State, Heap, Option[Term], Verifier) => VerificationResult)
: VerificationResult = {
private def consume2(s: State,
h: Heap,
resource: ast.Resource,
args: Seq[Term],
perms: Term,
ve: VerificationError,
v: Verifier)
(Q: (State, Heap, Option[Term], Verifier) => VerificationResult)
: VerificationResult = {

val id = ChunkIdentifier(resource, Verifier.program)
if (s.exhaleExt) {
Expand Down Expand Up @@ -185,31 +185,15 @@ object chunkSupporter extends ChunkSupportRules {
Q(s.copy(functionRecorder = fr1), h1, v)
}

@inline
def lookup(s: State,
h: Heap,
resource: ast.Resource,
args: Seq[Term],
ve: VerificationError,
v: Verifier,
description: String)
v: Verifier)
(Q: (State, Heap, Term, Verifier) => VerificationResult)
: VerificationResult = {

heuristicsSupporter.tryOperation[Heap, Term](description)(s, h, v)((s1, h1, v1, QS) => {
lookup(s1, h1, resource, args, ve, v1)(QS)
})(Q)
}

private def lookup(s: State,
h: Heap,
resource: ast.Resource,
args: Seq[Term],
ve: VerificationError,
v: Verifier)
(Q: (State, Heap, Term, Verifier) => VerificationResult)
: VerificationResult = {

executionFlowController.tryOrFail2[Heap, Term](s.copy(h = h), v)((s1, v1, QS) => {
val lookupFunction =
if (s.isMethodVerification && Verifier.config.enableMoreCompleteExhale()) moreCompleteExhaleSupporter.lookupComplete _
Expand Down
Loading