-
Notifications
You must be signed in to change notification settings - Fork 53
Experiment with nonterminating programs #481
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
base: master
Are you sure you want to change the base?
Conversation
(i could make it true, but it's not clearly worth the effort.) instead, i will just do the prefix spec
5bc17f5 to
7075a56
Compare
|
Actually, the problem I was trying to solve here, using the formulas-embedded-in-program-states thing, has a much simpler solution. Given a predicate (Here, we assume some function
alternatively:
The same trick works with big-step omnisemantics, assuming it's been augmented with the |
I am not actually requesting that this be pulled, but maybe it is interesting.
This branch's version of MetricLeakageSemantics uses a version of omnisemantics that allows proving things about nonterminating programs. There are two ingredients to this:
execpredicate; this rule allows the program to quit executing at an arbitrary point, so that a "midcondition" may be asserted about the state at this point. This also requires an extra bitqof program state, a boolean tracking whether the program is still executing or has already quit.aep, of typeAEP. This (unfortunate) name alludes to the type's three constructors: one constructor representing a for-All quantifier, one constructor representing an Exists quantifier, and one constructor (the base case) representing a Predicate---this predicate is, more or less, a midcondition. (For no real reason, quantifiers here are restricted to bind nats.)The idea is that the predicate to be proved evolves as the program runs. For-all quantifiers are discharged via demonic nondeterminism, and exists quantifiers are discharged via angelic nondeterminism. After discharging all quantifiers, you are left with a midcondition, which may be then asserted upon the program's state.
For example, the
eventual_one_printerpicks a random natural numberx, prints the zero characterxtimes, and then prints the one character in an infinite loop. The spec of the eventual one printer says that its I/O trace has a tail of ones.This way of talking about nonterminating programs seems a bit strange, but the nice thing is that it's not much bother when writing compiler proofs. The extra proof obligations generated by the
quitrule are a bit annoying but straightforward to handle. On the other hand, the proof obligations coming from theexistsandforallquantifier-discharging rules tend to be trivial.One difficulty caused by adding the extra inference rules to
execis thatexecthen fails to be syntax-directed: the quit rule, the forall-discharging rule, and the exists-discharging rule always apply, regardless of which command is being considered. This means that using theinversiontactic on hypotheses of the formexec s q aep k t m l mc postgives multiple goals (some of which are no easier than the original), even when the head ofsis known. To do inversion effectively, you can prove an "inversion lemma" like this.I proved that augmenting the program state with the
AEPthing allows you to express, using small-step omnisemantics, any desired predicate about the trace of a program---provided that the program is either reactive (infinite trace) or terminating. I didn't write a formal proof that just as many trace predicates are expressible using big-step omnisemantics, but it is obviously true. However, there are limitations about diverging programs (i.e., nonterminating programs with finite traces); for instance, one cannot write a postcondition saying that a program diverges with a particular finite trace.The compiler theorem in this branch has a source language defined by an
execpredicate involving theAEPandquitthings, but it's reassuring that the target language does not involve these things. The target language is still just regular small-step omnisemantics. For example, the high-level spec of the eventual one printer implies this low-level spec.