-
Notifications
You must be signed in to change notification settings - Fork 44
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
Auto-generating well-foundedness axioms for ADT types in the ADT plugin #743
Conversation
I have two comments about the design, one about unexpected results and the other about completeness.
adt Stream = Stream(x: Int, s: Stream) The existence of a value of this type implies false in this scenario. An inexperienced user may be confused that the following verifies: decreases s
function mapPlusOne(s: Stream): Stream {
Stream(s.x + 1, mapPlusOne(s.s))
} The successful verification is correct, but if a user is not aware that ADTs are inductive, they may expect a termination error here. It is unclear to me what would be the best way to avoid surprising users here. At any rate, a possibility could be to extend the second axiom to sth like axiom {
forall t: T :: { C1(t) } (hasBaseCase() ==> bounded(C1(t))) && decreasing(t, C1(t))
}
adt List1 = List1(x: Int, l: List2)
adt List2 = Empty | NonEmpty(l: List2)
decreases l
function len(l: List2): Int {
l == Empty? 0 : 1 + len(l.l) // cannot prove that l.l < l
} This is not such a big deal because the user can always override the termination measures, but may be a bit annoying. |
Thanks! |
I've come to terms with allowing the snippet I showed in Point 1 to verify. Trying to avoid this particular surprising behaviour sounds like enumerating badness. Doing so is more consistent with what we do for preconditions (we do NOT try to find out whether they are satisfiable). Another option would be to simply not generate a well founded order for ADTs without a base case, although I would prefer some static check that rejects ADT definitions like this |
Okay, mutually recursive ADT definitions are now supported. |
This PR extends the ADT plugin to generate an additional domain
TWellFoundedOrder
for every ADT typeT
that constrains thedecreasing
andbounded
functions used in termination checks in the obvious way, so that users can write clauses likedecreases t
for a parametert
of an ADT type by default.The additional domain is generated for an ADT type
T
iff:WellFoundedOrder
domain, i.e., thedecreasing
andbounded
functions are actually declaredTWellFoundedOrder
, i.e., there is no user-provided definition of the well-foundedness order for this type yet.The generated domain for type
T
and recursive constructorC1(T)
and non-recursive constructorC2(V)
looks as follows: