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

Advanced logical proofs #785

Open
wants to merge 54 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
9c034cc
Existential Elimination v1
dinanoe Nov 9, 2022
c229ac5
Merge branch 'master' of https://github.com/dinanoe/silver
dinanoe Nov 9, 2022
a2c5c6d
Existential Elimination added Trigger typecheck
dinanoe Nov 9, 2022
1b56187
Existential Elimination comments
dinanoe Nov 9, 2022
8704df5
Merge branch 'viperproject:master' into master
dinanoe Nov 15, 2022
2eba4da
Universal Introduction v1
dinanoe Nov 16, 2022
2b2211f
Added Flow Analysis with Graph
dinanoe Feb 14, 2023
76ed0cd
oldCall added, restructured Code
dinanoe Feb 25, 2023
37429f9
merge1
dinanoe Feb 25, 2023
2118cef
Complete Bachelor Thesis
dinanoe Mar 21, 2023
ab682a9
Merge branch 'viperproject:master' into master
dinanoe Apr 16, 2023
437b56c
Merge branch 'master' into master
ArquintL Apr 20, 2023
7dc7952
Merges tag 'v.24.01-release' into 'advanced-logical-proofs'
ArquintL Feb 28, 2024
663797f
fixes parser to correctly parse syntax of reasoning plugin
ArquintL Feb 27, 2024
abe8a9c
reduces diff
ArquintL Feb 27, 2024
3195a8d
adds license headers
ArquintL Feb 27, 2024
0c0efd7
fixes a compiler error
ArquintL Feb 27, 2024
3da1caf
changes testcases that use 'heap', which is now a keyword
ArquintL Feb 27, 2024
c217565
cleans up reasoning plugin further
ArquintL Feb 28, 2024
383a4df
Merges branch 'master' into 'advanced-logical-proofs'
ArquintL Feb 28, 2024
4847f56
changes yet another testcase that uses 'heap', which is now a keyword
ArquintL Feb 28, 2024
7d05083
first version of graph map taint analysis
jgaAdibilis Apr 9, 2024
4153019
added assume analysis & modular method analysis
jgaAdibilis Apr 16, 2024
2e6d4e5
fix a bug in method handling & rename variables
jgaAdibilis Apr 16, 2024
9a5b903
ordered tests
jgaAdibilis Apr 16, 2024
e558efa
add more tests & cleanup
jgaAdibilis Apr 18, 2024
8e1efab
remove logs
jgaAdibilis Apr 18, 2024
290bfa3
Merge remote-tracking branch 'origin/master' into advanced-logical-pr…
jgaAdibilis Apr 18, 2024
191a812
remove todo
jgaAdibilis Apr 18, 2024
04de8bc
add missing position information to ImpureAssumeRewriter
jgaAdibilis Apr 18, 2024
f79936a
fix method analysis modularity
jgaAdibilis Apr 29, 2024
6d6179c
add assumesNothing spec to specify that a method contains no assume/i…
jgaAdibilis May 21, 2024
b4a1086
update recursive methods & add noAssumes check
jgaAdibilis May 21, 2024
81f9b62
Merge branch 'master' into advanced-logical-proofs
ArquintL Jun 2, 2024
90a763b
treat non-terminating loop as assume statement & some cleanup
jgaAdibilis Jun 17, 2024
a25d1ae
Merge remote-tracking branch 'origin/advanced-logical-proofs' into ad…
jgaAdibilis Jun 17, 2024
23a3a4b
Merge remote-tracking branch 'origin/master' into advanced-logical-pr…
jgaAdibilis Jun 17, 2024
a814df4
change position of reported error
jgaAdibilis Jun 17, 2024
cf0fea1
Update src/main/scala/viper/silver/plugin/standard/reasoning/Reasonin…
jogasser Jun 24, 2024
78960ff
Update src/main/scala/viper/silver/plugin/standard/reasoning/BeforeVe…
jogasser Jun 24, 2024
e93fd6b
Update src/main/scala/viper/silver/plugin/standard/reasoning/BeforeVe…
jogasser Jun 24, 2024
695c91b
Apply suggestions from code review
jogasser Jun 24, 2024
9bb7f88
Apply suggestions from code review
jogasser Jun 24, 2024
a0617ce
address mr comments
jgaAdibilis Jun 24, 2024
a452e1d
split AssumeNode into multiple AssumeNodes for better error reporting
jgaAdibilis Jun 24, 2024
ab3e166
split veforeVerify method
jgaAdibilis Jun 24, 2024
20cf3e9
add assume to pretty print
jgaAdibilis Jun 24, 2024
f0476da
improves type guarantees of modular taint analysis and fixes terminat…
ArquintL Jun 30, 2024
33e0b33
fix a bug where local variables in methods were not correctly cleaned…
jgaAdibilis Jul 1, 2024
1d36454
remove local variables from calculated influences before they are che…
jgaAdibilis Jul 1, 2024
62b2649
Merge branch 'advanced-logical-proofs' into arquintl-advanced-logical…
ArquintL Jul 2, 2024
3362648
Merge pull request #1 from viperproject/arquintl-advanced-logical-proofs
jogasser Jul 8, 2024
1e41b5e
remove TODO
jgaAdibilis Jul 8, 2024
8f2fa05
add test, fix positioning & block placement
jgaAdibilis Jul 15, 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
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ object ImpureAssumeRewriter {
assert(conds.isEmpty)
assert(cond.isEmpty)

PermGeCmp(permLoc, perm)()
PermGeCmp(permLoc, perm)(permLoc.pos, permLoc.info, permLoc.errT)
} else {
val perms: Seq[Exp] = (contextWithoutRcv map (_._2)) :+ perm

Expand All @@ -146,7 +146,7 @@ object ImpureAssumeRewriter {
val func = funcs(contextWithoutRcv.length-1)
val funcApp = DomainFuncApp(func, conds ++ perms, Map[TypeVar, Type]())()

PermGeCmp(permLoc, funcApp)()
PermGeCmp(permLoc, funcApp)(permLoc.pos, permLoc.info, permLoc.errT)
}
}

Expand Down
1 change: 1 addition & 0 deletions src/main/scala/viper/silver/frontend/SilFrontend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ trait SilFrontend extends DefaultFrontend {
"viper.silver.plugin.standard.adt.AdtPlugin",
"viper.silver.plugin.standard.termination.TerminationPlugin",
"viper.silver.plugin.standard.predicateinstance.PredicateInstancePlugin",
"viper.silver.plugin.standard.reasoning.ReasoningPlugin",
refutePlugin
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// 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))
}

/**
* get all variables that are assigned to inside the block and take intersection with universal introduction
* variables. If they are contained throw error since these variables should be immutable
jogasser marked this conversation as resolved.
Show resolved Hide resolved
*
* @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))
}
}

jogasser marked this conversation as resolved.
Show resolved Hide resolved
private def specifiesLemma(m: Method): Boolean = (m.pres ++ m.posts).exists {
jogasser marked this conversation as resolved.
Show resolved Hide resolved
case _: Lemma => true
case _ => false
}

/** check if isLemma precondition is correct */
def checkLemma(input: Program, reportError: AbstractError => Unit): Unit = {
jogasser marked this conversation as resolved.
Show resolved Hide resolved
input.methods.foreach(method => {
val containsLemma = specifiesLemma(method)
val (containsDecreases, containsDecreasesStar) = AnalysisUtils.containsDecreasesAnnotations(method)

if (containsLemma) {
/** report error if there is no decreases clause or specification */
if(!containsDecreases) {
reportError(ConsistencyError(s"method ${method.name} marked lemma might not contain decreases clause", method.pos))
jogasser marked this conversation as resolved.
Show resolved Hide resolved
}

/** report error if the decreases statement might not prove termination */
if (containsDecreasesStar) {
reportError(ConsistencyError("decreases statement might not prove termination", method.pos))
jogasser marked this conversation as resolved.
Show resolved Hide resolved
}

/** check method body for impure statements */
checkBodyPure(method.body.getOrElse(Seqn(Seq(), Seq())()), method, input, reportError)
}
})
}

/** checks whether the body is pure, reports error if impure operation found */
def checkBodyPure(stmt: Stmt, method: Method, prog: Program, reportError: AbstractError => Unit): Boolean = {
jogasser marked this conversation as resolved.
Show resolved Hide resolved
var pure: Boolean = true
jogasser marked this conversation as resolved.
Show resolved Hide resolved
stmt match {
case Seqn(ss, _) =>
ss.foreach(s => {
pure = pure && checkBodyPure(s, method, prog, reportError)
})
pure
jogasser marked this conversation as resolved.
Show resolved Hide resolved

/** 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 containsLemma = specifiesLemma(mc)

/** if called method is not a lemma report error */
if (!containsLemma) {
reportError(ConsistencyError(s"method ${method.name} marked lemma might contain call to method ${m}", m.pos))
false
} else {
pure
}
jogasser marked this conversation as resolved.
Show resolved Hide resolved
case _ =>
pure
jogasser marked this conversation as resolved.
Show resolved Hide resolved
}
}

/** checks that influences by annotations are used correctly. */
jogasser marked this conversation as resolved.
Show resolved Hide resolved
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.AssumeNode(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 variables can be influenced. ${targetVarDecl.name} is not be a return variable.", v.pos))
jogasser marked this conversation as resolved.
Show resolved Hide resolved
}
if (seenVars.contains(targetVarDecl)) {
reportError(ConsistencyError(s"Only one influenced by expression per return variable can exist. ${targetVarDecl.name} is used several times.", v.pos))
jogasser marked this conversation as resolved.
Show resolved Hide resolved
}
seenVars.add(targetVarDecl)

args.foreach(arg => {
val argVarDecl = AnalysisUtils.getLocalVarDeclFromFlowVar(arg)
if (!argVars.contains(argVarDecl)) {
reportError(ConsistencyError(s"Only method arguments can influence a return variable. ${argVarDecl.name} is not be a method argument.", v.pos))
jogasser marked this conversation as resolved.
Show resolved Hide resolved
}
})
case _ => ()
jogasser marked this conversation as resolved.
Show resolved Hide resolved
}
})
}
}
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 quantifier must be of Bool type, but found ${exp.typ}", exp.pos)) else Seq()) ++
(if (varList.isEmpty) Seq(ConsistencyError("Quantifier must have at least one quantified variable.", pos)) else Seq())
jogasser marked this conversation as resolved.
Show resolved Hide resolved

override lazy val prettyPrint: PrettyPrintPrimitives#Cont = {
text("obtain") <+> showVars(varList) <+>
text("where") <+> (if (trigs.isEmpty) nil else space <> ssep(trigs map show, space)) <+>
jogasser marked this conversation as resolved.
Show resolved Hide resolved
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], exp1: Exp, exp2: Exp, block: Seqn)(val pos: Position = NoPosition, val info: Info = NoInfo, val errT: ErrorTrafo = NoTrafos) extends ExtensionStmt with Scope {
jogasser marked this conversation as resolved.
Show resolved Hide resolved
// See also Expression Line 566
override lazy val check: Seq[ConsistencyError] =
(if (!(exp1 isSubtype Bool)) Seq(ConsistencyError(s"Body of universal quantifier must be of Bool type, but found ${exp1.typ}", exp1.pos)) else Seq()) ++
(if (varList.isEmpty) Seq(ConsistencyError("Quantifier must have at least one quantified variable.", pos)) else Seq()) ++
jogasser marked this conversation as resolved.
Show resolved Hide resolved
Consistency.checkAllVarsMentionedInTriggers(varList, triggers)

override val scopedDecls: Seq[Declaration] = varList

override lazy val prettyPrint: PrettyPrintPrimitives#Cont = {
text("prove forall") <+> showVars(varList) <+>
text("assuming") <+>
toParenDoc(exp1) <+>
text("implies") <+> toParenDoc(exp2) <+>
jogasser marked this conversation as resolved.
Show resolved Hide resolved
showBlock(block)
}

override val extensionSubnodes: Seq[Node] = varList ++ triggers ++ Seq(exp1, exp2, block)
jogasser marked this conversation as resolved.
Show resolved Hide resolved
}

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)))
}
}

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 FlowVar {
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 FlowVar {
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[FlowVar])(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 _ => 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] = {
var s = Seq.empty[ConsistencyError]
if (!Consistency.noResult(this))
s :+= ConsistencyError("Result variables are only allowed in postconditions of functions.", pos)
if (!Consistency.noDuplicates(rets))
s :+= ConsistencyError("Targets are not allowed to have duplicates", rets.head.pos)
s ++= args.flatMap(Consistency.checkPure)
s
jogasser marked this conversation as resolved.
Show resolved Hide resolved
}

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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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"
jogasser marked this conversation as resolved.
Show resolved Hide resolved
override val text = " no witness could be found."
jogasser marked this conversation as resolved.
Show resolved Hide resolved

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"
jogasser marked this conversation as resolved.
Show resolved Hide resolved
override val text = " not true for all vars."
jogasser marked this conversation as resolved.
Show resolved Hide resolved

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 FlowAnalysisFailed(override val offendingNode: ErrorNode, override val reason: ErrorReason, override val cached: Boolean = false) extends ExtensionAbstractVerificationError {
override val id = "flow analysis.failed"
override val text = " ."

override def withNode(offendingNode: errors.ErrorNode = this.offendingNode): FlowAnalysisFailed =
FlowAnalysisFailed(this.offendingNode, this.reason, this.cached)

override def withReason(r: ErrorReason): FlowAnalysisFailed = FlowAnalysisFailed(offendingNode, r, cached)
}
jogasser marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading