-
Notifications
You must be signed in to change notification settings - Fork 48
Advanced logical proofs #785
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
Open
jogasser
wants to merge
54
commits into
viperproject:master
Choose a base branch
from
jogasser:advanced-logical-proofs
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 47 commits
Commits
Show all changes
54 commits
Select commit
Hold shift + click to select a range
9c034cc
Existential Elimination v1
dinanoe c229ac5
Merge branch 'master' of https://github.com/dinanoe/silver
dinanoe a2c5c6d
Existential Elimination added Trigger typecheck
dinanoe 1b56187
Existential Elimination comments
dinanoe 8704df5
Merge branch 'viperproject:master' into master
dinanoe 2eba4da
Universal Introduction v1
dinanoe 2b2211f
Added Flow Analysis with Graph
dinanoe 76ed0cd
oldCall added, restructured Code
dinanoe 37429f9
merge1
dinanoe 2118cef
Complete Bachelor Thesis
dinanoe ab682a9
Merge branch 'viperproject:master' into master
dinanoe 437b56c
Merge branch 'master' into master
ArquintL 7dc7952
Merges tag 'v.24.01-release' into 'advanced-logical-proofs'
ArquintL 663797f
fixes parser to correctly parse syntax of reasoning plugin
ArquintL abe8a9c
reduces diff
ArquintL 3195a8d
adds license headers
ArquintL 0c0efd7
fixes a compiler error
ArquintL 3da1caf
changes testcases that use 'heap', which is now a keyword
ArquintL c217565
cleans up reasoning plugin further
ArquintL 383a4df
Merges branch 'master' into 'advanced-logical-proofs'
ArquintL 4847f56
changes yet another testcase that uses 'heap', which is now a keyword
ArquintL 7d05083
first version of graph map taint analysis
jgaAdibilis 4153019
added assume analysis & modular method analysis
jgaAdibilis 2e6d4e5
fix a bug in method handling & rename variables
jgaAdibilis 9a5b903
ordered tests
jgaAdibilis e558efa
add more tests & cleanup
jgaAdibilis 8e1efab
remove logs
jgaAdibilis 290bfa3
Merge remote-tracking branch 'origin/master' into advanced-logical-pr…
jgaAdibilis 191a812
remove todo
jgaAdibilis 04de8bc
add missing position information to ImpureAssumeRewriter
jgaAdibilis f79936a
fix method analysis modularity
jgaAdibilis 6d6179c
add assumesNothing spec to specify that a method contains no assume/i…
jgaAdibilis b4a1086
update recursive methods & add noAssumes check
jgaAdibilis 81f9b62
Merge branch 'master' into advanced-logical-proofs
ArquintL 90a763b
treat non-terminating loop as assume statement & some cleanup
jgaAdibilis a25d1ae
Merge remote-tracking branch 'origin/advanced-logical-proofs' into ad…
jgaAdibilis 23a3a4b
Merge remote-tracking branch 'origin/master' into advanced-logical-pr…
jgaAdibilis a814df4
change position of reported error
jgaAdibilis cf0fea1
Update src/main/scala/viper/silver/plugin/standard/reasoning/Reasonin…
jogasser 78960ff
Update src/main/scala/viper/silver/plugin/standard/reasoning/BeforeVe…
jogasser e93fd6b
Update src/main/scala/viper/silver/plugin/standard/reasoning/BeforeVe…
jogasser 695c91b
Apply suggestions from code review
jogasser 9bb7f88
Apply suggestions from code review
jogasser a0617ce
address mr comments
jgaAdibilis a452e1d
split AssumeNode into multiple AssumeNodes for better error reporting
jgaAdibilis ab3e166
split veforeVerify method
jgaAdibilis 20cf3e9
add assume to pretty print
jgaAdibilis f0476da
improves type guarantees of modular taint analysis and fixes terminat…
ArquintL 33e0b33
fix a bug where local variables in methods were not correctly cleaned…
jgaAdibilis 1d36454
remove local variables from calculated influences before they are che…
jgaAdibilis 62b2649
Merge branch 'advanced-logical-proofs' into arquintl-advanced-logical…
ArquintL 3362648
Merge pull request #1 from viperproject/arquintl-advanced-logical-proofs
jogasser 1e41b5e
remove TODO
jgaAdibilis 8f2fa05
add test, fix positioning & block placement
jgaAdibilis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
146 changes: 146 additions & 0 deletions
146
src/main/scala/viper/silver/plugin/standard/reasoning/BeforeVerifyHelper.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| // This Source Code Form is subject to the terms of the Mozilla Public | ||
| // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
| // | ||
| // Copyright (c) 2011-2024 ETH Zurich. | ||
|
|
||
| package viper.silver.plugin.standard.reasoning | ||
|
|
||
|
|
||
| import viper.silver.ast.utility.Expressions | ||
| import viper.silver.ast.{Apply, Declaration, Exhale, Exp, FieldAssign, Fold, Inhale, LocalVarDecl, Method, MethodCall, Package, Program, Seqn, Stmt, Unfold} | ||
| import viper.silver.verifier.{AbstractError, ConsistencyError} | ||
| import viper.silver.plugin.standard.reasoning.analysis.AnalysisUtils | ||
|
|
||
| import scala.collection.mutable | ||
|
|
||
| trait BeforeVerifyHelper { | ||
| /** methods to rename variables for the encoding of the new syntax */ | ||
| def uniqueName(name: String, usedNames: mutable.Set[String]): String = { | ||
| var i = 1 | ||
| var newName = name | ||
| while (usedNames.contains(newName)) { | ||
| newName = name + i | ||
| i += 1 | ||
| } | ||
| usedNames.add(newName) | ||
| newName | ||
| } | ||
|
|
||
| def substituteWithFreshVars[E <: Exp](vars: Seq[LocalVarDecl], exp: E, usedNames: mutable.Set[String]): (Seq[(LocalVarDecl, LocalVarDecl)], E) = { | ||
| val declMapping = vars.map(oldDecl => | ||
| oldDecl -> LocalVarDecl(uniqueName(oldDecl.name, usedNames), oldDecl.typ)(oldDecl.pos, oldDecl.info, oldDecl.errT)) | ||
| val transformedExp = applySubstitution(declMapping, exp) | ||
| (declMapping, transformedExp) | ||
| } | ||
|
|
||
| def applySubstitution[E <: Exp](mapping: Seq[(LocalVarDecl, LocalVarDecl)], exp: E): E = { | ||
| Expressions.instantiateVariables(exp, mapping.map(_._1.localVar), mapping.map(_._2.localVar)) | ||
| } | ||
|
|
||
| def applySubstitutionWithExp[E <: Exp](mapping: Seq[(LocalVarDecl, Exp)], exp: E): E = { | ||
| Expressions.instantiateVariables(exp, mapping.map(_._1.localVar), mapping.map(_._2)) | ||
| } | ||
|
|
||
| /** | ||
| * check that all variables (`modified_vars`) that are assigned to inside a universal introduction `u`'s block are | ||
| * distinct from the universal introduction `u`'s quantified variables `quantified_vars`. Otherwise, an error is | ||
| * reported via `reportError` since these quantified variables should be immutable. | ||
| * | ||
| * @param modified_vars: set of variables that were modified in a given statement | ||
| * @param quantified_vars: set of quantified variables in the universal introduction statement. | ||
| * @param reportError: Method to report the error when a qunatified variable was modified | ||
| * @param u: universal introduction statement, used for details in error message | ||
| */ | ||
| def checkReassigned(modified_vars: Set[LocalVarDecl], quantified_vars: Seq[LocalVarDecl], reportError: AbstractError => Unit, u: UniversalIntro): Unit = { | ||
| val reassigned_vars: Set[LocalVarDecl] = modified_vars.intersect(quantified_vars.toSet) | ||
| if (reassigned_vars.nonEmpty) { | ||
| val reassigned_names: String = reassigned_vars.mkString(", ") | ||
| val reassigned_pos: String = reassigned_vars.map(_.pos).mkString(", ") | ||
| reportError(ConsistencyError("Universal Introduction variable(s) (" + reassigned_names + ") might have been reassigned at position(s) (" + reassigned_pos + ")", u.pos)) | ||
| } | ||
| } | ||
|
|
||
| /** returns true if method `m` is annotated to be a lemma */ | ||
| def specifiesLemma(m: Method): Boolean = (m.pres ++ m.posts).exists { | ||
| case _: Lemma => true | ||
| case _ => false | ||
| } | ||
|
|
||
| /** Checks that all lemmas in `input` satisfy the syntactical restrictions and, otherwise, reports errors by invoking `reportError`. */ | ||
| def checkLemmas(input: Program, reportError: AbstractError => Unit): Unit = { | ||
| input.methods.foreach(method => { | ||
| val containsLemma = specifiesLemma(method) | ||
| val (containsDecreases, containsDecreasesStar) = AnalysisUtils.specifiesTermination(method) | ||
|
|
||
| if (containsLemma) { | ||
| /** report error if there is no decreases clause or specification */ | ||
| if(!containsDecreases) { | ||
| reportError(ConsistencyError(s"Lemmas must terminate but method ${method.name} marked lemma does not specify any termination measures", method.pos)) | ||
| } | ||
|
|
||
| /** report error if the decreases statement might not prove termination */ | ||
| if (containsDecreasesStar) { | ||
| reportError(ConsistencyError("Lemmas must terminate but method ${method.name} marked lemma specifies only incomplete termination measures", method.pos)) | ||
| } | ||
|
|
||
| /** check method body for impure statements */ | ||
| checkStmtPure(method.body.getOrElse(Seqn(Seq(), Seq())()), method, input, reportError) | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| /** checks whether a statement `stmt` is pure, reports error if impure operation found */ | ||
| def checkStmtPure(stmt: Stmt, method: Method, prog: Program, reportError: AbstractError => Unit): Boolean = { | ||
| stmt match { | ||
| case Seqn(ss, _) => | ||
| ss.forall(s => checkStmtPure(s, method, prog, reportError)) | ||
|
|
||
| /** case for statements considered impure */ | ||
| case ie@(Inhale(_) | Exhale(_) | FieldAssign(_, _) | Fold(_) | Unfold(_) | Apply(_) | Package(_, _)) => | ||
| reportError(ConsistencyError(s"method ${method.name} marked lemma might contain impure statement $ie", ie.pos)) | ||
| false | ||
| case m@MethodCall(methodName, _, _) => | ||
| val mc = prog.findMethod(methodName) | ||
| val isLemmaCall = specifiesLemma(mc) | ||
|
|
||
| /** if called method is not a lemma report error */ | ||
| if (!isLemmaCall) { | ||
| reportError(ConsistencyError(s"method ${method.name} marked lemma might contain call to method $m", m.pos)) | ||
| } | ||
jogasser marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| isLemmaCall | ||
| case _ => true | ||
| } | ||
| } | ||
|
|
||
| /** checks that all influences by annotations in `input` are used correctly. */ | ||
| def checkInfluencedBy(input: Program, reportError: AbstractError => Unit): Unit = { | ||
| input.methods.foreach(method => { | ||
| val argVars = method.formalArgs.toSet + AnalysisUtils.heapVertex | ||
| val retVars = method.formalReturns.toSet.asInstanceOf[Set[Declaration]] + AnalysisUtils.heapVertex + AnalysisUtils.AssumeMethodNode(method.pos) | ||
|
|
||
| val seenVars: mutable.Set[Declaration] = mutable.Set() | ||
| /** iterate through method postconditions to find flow annotations */ | ||
| method.posts.foreach { | ||
| case v@FlowAnnotation(target, args) => | ||
| val targetVarDecl = AnalysisUtils.getDeclarationFromFlowVar(target, method) | ||
|
|
||
| if (!retVars.contains(targetVarDecl)) { | ||
| reportError(ConsistencyError(s"Only return parameters, the heap or assumes can be influenced. ${targetVarDecl.name} is not be a return parameter.", v.pos)) | ||
| } | ||
| if (seenVars.contains(targetVarDecl)) { | ||
| reportError(ConsistencyError(s"Only one influenced by expression per return parameter can exist. ${targetVarDecl.name} is used several times.", v.pos)) | ||
| } | ||
| seenVars.add(targetVarDecl) | ||
|
|
||
| args.foreach(arg => { | ||
| val argVarDecl = AnalysisUtils.getLocalVarDeclFromFlowVar(arg) | ||
| if (!argVars.contains(argVarDecl)) { | ||
| reportError(ConsistencyError(s"Only method input parameters or the heap can influence a return parameter. ${argVarDecl.name} is not be a method input parameter.", v.pos)) | ||
| } | ||
| }) | ||
| case _ => | ||
| } | ||
| }) | ||
| } | ||
| } | ||
173 changes: 173 additions & 0 deletions
173
src/main/scala/viper/silver/plugin/standard/reasoning/ReasoningASTExtension.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| // This Source Code Form is subject to the terms of the Mozilla Public | ||
| // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
| // | ||
| // Copyright (c) 2011-2024 ETH Zurich. | ||
|
|
||
| package viper.silver.plugin.standard.reasoning | ||
|
|
||
| import viper.silver.ast._ | ||
| import viper.silver.ast.pretty.FastPrettyPrinter.{ContOps, brackets, char, defaultIndent, group, line, nest, nil, parens, show, showBlock, showVars, space, ssep, text, toParenDoc} | ||
| import viper.silver.ast.pretty.PrettyPrintPrimitives | ||
| import viper.silver.ast.utility.Consistency | ||
| import viper.silver.verifier.{ConsistencyError, Failure, VerificationResult} | ||
|
|
||
|
|
||
| case object ReasoningInfo extends FailureExpectedInfo | ||
|
|
||
| case class ExistentialElim(varList: Seq[LocalVarDecl], trigs: Seq[Trigger], exp: Exp)(val pos: Position = NoPosition, val info: Info = NoInfo, val errT: ErrorTrafo = NoTrafos) extends ExtensionStmt { | ||
| override lazy val check: Seq[ConsistencyError] = Consistency.checkPure(exp) ++ | ||
| (if (!(exp isSubtype Bool)) Seq(ConsistencyError(s"Body of existential elimination must be of Bool type, but found ${exp.typ}", exp.pos)) else Seq()) ++ | ||
| (if (varList.isEmpty) Seq(ConsistencyError("Existential elimination must have at least one quantified variable.", pos)) else Seq()) | ||
|
|
||
| override lazy val prettyPrint: PrettyPrintPrimitives#Cont = { | ||
| text("obtain") <+> showVars(varList) <+> | ||
| text("where") <+> (if (trigs.isEmpty) nil else ssep(trigs map show, space)) <+> | ||
| toParenDoc(exp) | ||
| } | ||
|
|
||
| override val extensionSubnodes: Seq[Node] = varList ++ trigs ++ Seq(exp) | ||
|
|
||
| /** declarations contributed by this statement that should be added to the parent scope */ | ||
| override def declarationsInParentScope: Seq[Declaration] = varList | ||
| } | ||
|
|
||
| case class UniversalIntro(varList: Seq[LocalVarDecl], triggers: Seq[Trigger], assumingExp: Exp, implyingExp: Exp, block: Seqn)(val pos: Position = NoPosition, val info: Info = NoInfo, val errT: ErrorTrafo = NoTrafos) extends ExtensionStmt with Scope { | ||
| // See also Expression Line 566 | ||
| override lazy val check: Seq[ConsistencyError] = | ||
| (if (!(assumingExp isSubtype Bool)) Seq(ConsistencyError(s"Assume expression of universal introduction must be of Bool type, but found ${assumingExp.typ}", assumingExp.pos)) else Seq()) ++ | ||
| (if (!(implyingExp isSubtype Bool)) Seq(ConsistencyError(s"Implies expression of universal introduction must be of Bool type, but found ${implyingExp.typ}", implyingExp.pos)) else Seq()) ++ | ||
| (if (varList.isEmpty) Seq(ConsistencyError("Quantifier must have at least one quantified variable.", pos)) else Seq()) ++ | ||
| Consistency.checkAllVarsMentionedInTriggers(varList, triggers) | ||
|
|
||
| override val scopedDecls: Seq[Declaration] = varList | ||
|
|
||
| override lazy val prettyPrint: PrettyPrintPrimitives#Cont = { | ||
| text("prove forall") <+> showVars(varList) <+> | ||
| text("assuming") <+> | ||
| toParenDoc(assumingExp) <+> | ||
| text("implies") <+> toParenDoc(implyingExp) <+> | ||
| showBlock(block) | ||
| } | ||
|
|
||
| override val extensionSubnodes: Seq[Node] = varList ++ triggers ++ Seq(assumingExp, implyingExp, block) | ||
| } | ||
|
|
||
| sealed trait FlowVar extends ExtensionExp { | ||
| override def extensionIsPure: Boolean = true | ||
|
|
||
| override def verifyExtExp(): VerificationResult = { | ||
| assert(assertion = false, "FlowAnalysis: verifyExtExp has not been implemented.") | ||
| Failure(Seq(ConsistencyError("FlowAnalysis: verifyExtExp has not been implemented.", pos))) | ||
| } | ||
| } | ||
|
|
||
| trait FlowVarOrHeap extends FlowVar | ||
|
|
||
| case class Assumes()(val pos: Position = NoPosition, val info: Info = NoInfo, val errT: ErrorTrafo = NoTrafos) extends FlowVar { | ||
| override val extensionSubnodes: Seq[Node] = Seq.empty | ||
| override def typ: Type = InternalType | ||
| override def prettyPrint: PrettyPrintPrimitives#Cont = PAssumesKeyword.keyword | ||
| } | ||
|
|
||
| case class Heap()(val pos: Position = NoPosition, val info: Info = NoInfo, val errT: ErrorTrafo = NoTrafos) extends FlowVarOrHeap { | ||
| override val extensionSubnodes: Seq[Node] = Seq.empty | ||
| override def typ: Type = InternalType | ||
| override def prettyPrint: PrettyPrintPrimitives#Cont = PHeapKeyword.keyword | ||
| } | ||
|
|
||
| case class Var(decl: LocalVar)(val pos: Position = NoPosition, val info: Info = NoInfo, val errT: ErrorTrafo = NoTrafos) extends FlowVarOrHeap { | ||
| override val extensionSubnodes: Seq[Node] = Seq(decl) | ||
| override def typ: Type = decl.typ | ||
| override def prettyPrint: PrettyPrintPrimitives#Cont = show(decl) | ||
| } | ||
|
|
||
| case class NoAssumeAnnotation()(val pos: Position = NoPosition, val info: Info = NoInfo, val errT: ErrorTrafo = NoTrafos) extends ExtensionExp with Node { | ||
| override def extensionIsPure: Boolean = true | ||
|
|
||
| override def extensionSubnodes: Seq[Node] = Seq() | ||
|
|
||
| override def typ: Type = Bool | ||
|
|
||
| override def verifyExtExp(): VerificationResult = { | ||
| assert(assertion = false, "FlowAnalysis: verifyExtExp has not been implemented.") | ||
| Failure(Seq(ConsistencyError("FlowAnalysis: verifyExtExp has not been implemented.", pos))) | ||
| } | ||
|
|
||
| /** Pretty printing functionality as defined for other nodes in class FastPrettyPrinter. | ||
| * Sample implementation would be text("old") <> parens(show(e)) for pretty-printing an old-expression. */ | ||
| override def prettyPrint: PrettyPrintPrimitives#Cont = { | ||
| text("assumes nothing") | ||
| } | ||
| } | ||
|
|
||
| case class FlowAnnotation(v: FlowVar, varList: Seq[FlowVarOrHeap])(val pos: Position = NoPosition, val info: Info = NoInfo, val errT: ErrorTrafo = NoTrafos) extends ExtensionExp with Node with Scope { | ||
| override def extensionIsPure: Boolean = true | ||
|
|
||
| override val scopedDecls: Seq[Declaration] = Seq() | ||
|
|
||
| override def typ: Type = Bool | ||
|
|
||
| override def verifyExtExp(): VerificationResult = { | ||
| assert(assertion = false, "FlowAnalysis: verifyExtExp has not been implemented.") | ||
| Failure(Seq(ConsistencyError("FlowAnalysis: verifyExtExp has not been implemented.", pos))) | ||
| } | ||
|
|
||
| override def extensionSubnodes: Seq[Node] = Seq(v) ++ varList | ||
|
|
||
| /** Pretty printing functionality as defined for other nodes in class FastPrettyPrinter. | ||
| * Sample implementation would be text("old") <> parens(show(e)) for pretty-printing an old-expression. */ | ||
| override def prettyPrint: PrettyPrintPrimitives#Cont = { | ||
| text("influenced") <+> (v match { | ||
| case value: Var => show(value.decl) | ||
| case _: Assumes => text("assumes") | ||
| case _: Heap => text("heap") | ||
| }) <+> | ||
| text("by") <+> | ||
| ssep(varList.map { | ||
| case value: Var => show(value.decl) | ||
| case _ => text("heap") | ||
| }, group(char(',') <> line(" "))) | ||
jogasser marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
| case class Lemma()(val pos: Position = NoPosition, val info: Info = NoInfo, val errT: ErrorTrafo = NoTrafos) extends ExtensionExp with Node with Scope { | ||
| override def extensionIsPure: Boolean = true | ||
|
|
||
| override val scopedDecls: Seq[Declaration] = Seq() | ||
|
|
||
| override def typ: Type = Bool | ||
|
|
||
| override def verifyExtExp(): VerificationResult = { | ||
| assert(assertion = false, "Lemma: verifyExtExp has not been implemented.") | ||
| Failure(Seq(ConsistencyError("Lemma: verifyExtExp has not been implemented.", pos))) | ||
| } | ||
|
|
||
| override def extensionSubnodes: Seq[Node] = Seq() | ||
|
|
||
| /** Pretty printing functionality as defined for other nodes in class FastPrettyPrinter. | ||
| * Sample implementation would be text("old") <> parens(show(e)) for pretty-printing an old-expression. */ | ||
| override def prettyPrint: PrettyPrintPrimitives#Cont = { | ||
| text("isLemma") | ||
| } | ||
| } | ||
|
|
||
| case class OldCall(methodName: String, args: Seq[Exp], rets: Seq[LocalVar], oldLabel: String)(val pos: Position = NoPosition, val info: Info = NoInfo, val errT: ErrorTrafo = NoTrafos) extends ExtensionStmt with Scope { | ||
| override val scopedDecls: Seq[Declaration] = Seq() | ||
|
|
||
| override lazy val check: Seq[ConsistencyError] = { | ||
| (if (Consistency.noResult(this)) Seq.empty else Seq(ConsistencyError("Result variables are only allowed in postconditions of functions.", pos))) ++ | ||
| (if (Consistency.noDuplicates(rets)) Seq.empty else Seq(ConsistencyError("Targets are not allowed to have duplicates", rets.head.pos))) ++ | ||
| args.flatMap(Consistency.checkPure) | ||
| } | ||
|
|
||
| override lazy val prettyPrint: PrettyPrintPrimitives#Cont = { | ||
| val call = text("oldCall") <> brackets(text(oldLabel)) <> text(methodName) <> nest(defaultIndent, parens(ssep(args map show, group(char(',') <> line)))) | ||
| rets match { | ||
| case Nil => call | ||
| case _ => ssep(rets map show, char(',') <> space) <+> ":=" <+> call | ||
| } | ||
| } | ||
|
|
||
| override val extensionSubnodes: Seq[Node] = args ++ rets | ||
| } | ||
39 changes: 39 additions & 0 deletions
39
src/main/scala/viper/silver/plugin/standard/reasoning/ReasoningErrors.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| // This Source Code Form is subject to the terms of the Mozilla Public | ||
| // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
| // | ||
| // Copyright (c) 2011-2024 ETH Zurich. | ||
|
|
||
| package viper.silver.plugin.standard.reasoning | ||
|
|
||
| import viper.silver.verifier._ | ||
| import viper.silver.verifier.reasons.ErrorNode | ||
|
|
||
| case class ExistentialElimFailed(override val offendingNode: ErrorNode, override val reason: ErrorReason, override val cached: Boolean = false) extends ExtensionAbstractVerificationError { | ||
| override val id = "existential.elimination.failed" | ||
| override val text = "Existentially quantified formula might not hold." | ||
|
|
||
| override def withNode(offendingNode: errors.ErrorNode = this.offendingNode): ExistentialElimFailed = | ||
| ExistentialElimFailed(this.offendingNode, this.reason, this.cached) | ||
|
|
||
| override def withReason(r: ErrorReason): ExistentialElimFailed = ExistentialElimFailed(offendingNode, r, cached) | ||
| } | ||
|
|
||
| case class UniversalIntroFailed(override val offendingNode: ErrorNode, override val reason: ErrorReason, override val cached: Boolean = false) extends ExtensionAbstractVerificationError { | ||
| override val id = "universal.introduction.failed" | ||
| override val text = "Specified property might not hold." | ||
|
|
||
| override def withNode(offendingNode: errors.ErrorNode = this.offendingNode): UniversalIntroFailed = | ||
| UniversalIntroFailed(this.offendingNode, this.reason, this.cached) | ||
|
|
||
| override def withReason(r: ErrorReason): UniversalIntroFailed = UniversalIntroFailed(offendingNode, r, cached) | ||
| } | ||
|
|
||
jogasser marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| case class PreconditionInLemmaCallFalse(offendingNode: OldCall, reason: ErrorReason, override val cached: Boolean = false) extends ExtensionAbstractVerificationError { | ||
| val id = "lemma.call.precondition" | ||
| val text = s"The precondition of lemma ${offendingNode.methodName} might not hold." | ||
|
|
||
| def withNode(offendingNode: errors.ErrorNode = this.offendingNode): PreconditionInLemmaCallFalse = PreconditionInLemmaCallFalse(offendingNode.asInstanceOf[OldCall], this.reason, this.cached) | ||
|
|
||
| def withReason(r: ErrorReason): PreconditionInLemmaCallFalse = PreconditionInLemmaCallFalse(offendingNode, r, cached) | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.