-
Notifications
You must be signed in to change notification settings - Fork 13
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
Introduce result class #26
base: master
Are you sure you want to change the base?
Conversation
mkString(PrepareACSLPrinting(i))))) | ||
} | ||
|
||
// SSSOWO TODO: This doesn't seem to be used anywhere. Remove? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zafer-esen Please advice on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, I think these are just remnants of the Princess' lineariser code that we started with.
(result: Either[Option[HornPreprocessor.Solution], hornconcurrency.VerificationLoop.Counterexample]) | ||
: Result = { | ||
import scala.collection.mutable.HashSet | ||
// SSSOWO TODO: These constants should be defined in a single place. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zafer-esen Please advice on how to go forward here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe collect internal parameters/constants like these in a new class under src/tricera/params/
? We could also be able to eliminate these altogether, but that's probably work for another PR.
subres: Seq[IExpression] | ||
): IExpression = { | ||
t update subres match { | ||
// SSSOWO TODO: Why does this need special handling? "emptyHeap" is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zafer-esen Do you have any comment on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it needs special handling. We probably just missed this, relying on function names and string comparisons is not a good idea. I think we also do not need to use TheoryOfHeapFunApp
in general here. That is useful when, given some IFunction
, we do not have the heap theory (an object of the Heap
class) and we want to get the heap theory if the function matches one of the theory functions.
Here we already have the heap theory in heapInfo
, so why not simply do:
case IFunApp(f, _) if heapInfo.isEmptyHeapFun(f)
and similarly for the other cases.
@@ -225,6 +226,9 @@ object ValSetReader { | |||
extends CollectingVisitor[Unit, ValSet] | |||
with ExpressionUtils { | |||
|
|||
// SSSOWO: The de Bruijn version disregards disjunctions, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zafer-esen To mee this looks really weird. The deBruijn version and the "invariant" version treat disjunctions differently. I actually think the deBruijn version is correct and that this implementation may cause some to the problems discussed in issue #15. But I think we need to have a closer look on what to do with disjunctions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I think we should just add this as a note to #15 and do the closer look when resolving that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR looks like a great step in the right direction, thanks for contributing it!
I left a few minor comments and tried to address the questions. I think we can merge it after addressing those and you give the green light.
subres: Seq[IExpression] | ||
): IExpression = { | ||
t update subres match { | ||
// SSSOWO TODO: Why does this need special handling? "emptyHeap" is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it needs special handling. We probably just missed this, relying on function names and string comparisons is not a good idea. I think we also do not need to use TheoryOfHeapFunApp
in general here. That is useful when, given some IFunction
, we do not have the heap theory (an object of the Heap
class) and we want to get the heap theory if the function matches one of the theory functions.
Here we already have the heap theory in heapInfo
, so why not simply do:
case IFunApp(f, _) if heapInfo.isEmptyHeapFun(f)
and similarly for the other cases.
val result = verificationLoop.result | ||
.tapIf(displaySolutionProlog)(printSolutionProlog(reader.PredPrintContext.predArgNames)) | ||
.tapIf(lazabs.GlobalParameters.get.displaySolutionSMT)(printSolutionSMT) | ||
.through(hornSolverSolutionToResult(reader)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like the simplification here!
One question is, does the result conversion always run now? I think it would be good to have an option to toggle it.
mkString(PrepareACSLPrinting(i))))) | ||
} | ||
|
||
// SSSOWO TODO: This doesn't seem to be used anywhere. Remove? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, I think these are just remnants of the Princess' lineariser code that we started with.
import scala.collection.mutable.{Set, HashSet} | ||
import tricera.Util.printlnDebug | ||
|
||
object PostconditionSimplifier extends ResultProcessor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this class can be made much more efficient (not related to this PR), but that's for another PR...
(result: Either[Option[HornPreprocessor.Solution], hornconcurrency.VerificationLoop.Counterexample]) | ||
: Result = { | ||
import scala.collection.mutable.HashSet | ||
// SSSOWO TODO: These constants should be defined in a single place. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe collect internal parameters/constants like these in a new class under src/tricera/params/
? We could also be able to eliminate these altogether, but that's probably work for another PR.
@@ -225,6 +226,9 @@ object ValSetReader { | |||
extends CollectingVisitor[Unit, ValSet] | |||
with ExpressionUtils { | |||
|
|||
// SSSOWO: The de Bruijn version disregards disjunctions, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I think we should just add this as a note to #15 and do the closer look when resolving that.
tmp/example.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was the tmp
directory added intentionally?
.through(ADTExploder.apply) | ||
.through(FunctionInvariantsFilter(i => !i.isSrcAnnotated)(_)) | ||
.through(r => | ||
if (solution.isHeapUsed) { r |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the previous comment, I think there should be an option to use log
, but not run the processors (at least until we fix the performance of PostconditionSimplifier
). With displayACSL
it makes sense to do the simplification by default though.
Summary
This PR introduces a
Result
trait and related classes in order to introduce more structure into the post processing of the result from the horn solver. Therefore this PR makes substantial changes to these parts of the code, especially the post-processors related to translation of explicit heap into implicit form more suitable for ACSL contract generation.An ambition has been to introduce an interface between the translator (
CCReader
) the solver and the result. A major change is a move away from the existingFunctionContext
andACSLTranslator.FunctionContext
. These classes kept too much information in a form tightly bound to the problem description for them to be practical to use.the
ResultConverter.hornSolverSolutionToResult()
converts the solution from the horn solver and data fromCCReader
into aSolution
result (see below). As part of this conversion, the predicate variables representing program variables of some kind (globals, parameters, or locals in the case of loop invariants) are replaced with symbolic constants. However, in order to keep necessary meta data about them theIConstant
is instantiated with a special type of constant,ProgVarProxy
, derived fromConstantTerm
. That way they can be separated from any other constant in the expressions.ProgVarProxy
does not rely on prefix or suffix information in the name in order to keep track of various attributes. Instead such informtion is kept in separate variables.Introduced concepts
Result
trait. A container for a the result. There are case classes forEmpty
,CounterExample
andSolution
.Solution
is a set ofFunctionInvariants
, one for each function we are inferring contracts for.FunctionInvariant
is aPreCondition
,PostCondition
, andLoopInvariants
and some meta-data.PreCondition
,PostCondition
, andLoopInvariants
are cases extending theInvariantContext
trait.PreCondition
andPostCondition
each contains anInvariant
.Invariant
is a container for anIFormula
and some meta-data for heap operations.HeapInfo
is a class that contains information regarding the heap and objects and functions related to that.ProgVarProxy
is derived fromConstantTerm
and is used as a proxy for program variables inIFormula
andIExpressions
.ProgVarProxy
carries meta data about scope (global, parameter etc.) and context (pre-execution, post-execution). This is utilized in ACSL contract generation.Comments
ValSetReader
EqualitySwapper
and friends. I can't see this being necessary anymore, since all free variables are replaced by symbolic constants before any processing is started. However, I noticed some differences in their implementation and have therefore kept both. This needs further consideration