-
Notifications
You must be signed in to change notification settings - Fork 62
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
Uninterpreted higher-order functions #906
Comments
Adding the function name to the error message will be very easy. I can make a PR for this right away. I've thought about supporting uninterpreted higher-order functions. There are a couple of reasons why this is trickier to implement than supporting uninterpreted polymorphic functions. To support polymorphic functions, we only need a way to map from a pair of (function name, list of type arguments) to an uninterpreted function symbol. This is pretty easy to do because we can fully inspect the type argument values and compare them for equality. For higher-order functions like Another approach would be to ignore the higher-order function arguments completely, and just generate a fresh uninterpreted function symbol whenever we encounter a sufficiently-applied higher-order function. We could rely on the observable subterm sharing to ensure that multiple occurrences of the same higher-order function applied to the same function argument would map to the same uninterpreted function symbol in the backend. This might be a bit too fragile, though: Beta-reduction would probably affect whether or not two uses of the same higher-order function were unified or not. For example, if a larger term contained both |
This partially addresses GaloisInc/saw-script#906.
You write "we don't have a good way to inspect the function arguments or compare them for equality", and yet, when the rewrite rule applies, some version of this must be happening. But this is perhaps very weak. In the cases I'm encountering, the higher-order argument is always a named function but I can appreciate that this would not always be the case. The example of |
Right, the rewriter is operating purely on syntax, and it does syntactic matching. But the uninterpreted functions are being created in the context of an evaluation backend, where all function arguments are converted from |
That does make sense. I can certainly live with things as they are now, but it makes some of the proofs uglier than I'd like. |
This is definitely a feature that I'd like to support eventually; it just might take a while before we get there. |
This partially addresses GaloisInc/saw-script#906.
This partially addresses GaloisInc/saw-script#906.
I have a renewed interest in getting this implemented now, because uninterpreted higher-order functions would be important for doing faithful round-trip translations back and forth between saw-core and what4. This kind of round-tripping is useful not just for I'm starting to think that switching the saw-core |
SAW could be more informative in its error message here. With these definitions
we get the error message
In this case that function is obviously
twice
, but in a more complicated scenario with many uninterpreted names it can take a while to find the culprit. Surely SAW could print the name of the offending function here.Even better, though, would be to support uninterpreted higher-order functions, similarly to the way uninterpreted polymorphic functions were recently supported.
The work around I use for now involves a cover function, e.g.,
with a rewrite rule
then simplifying with this rule before generating the goal
While this is bearable for a small proof like this, it is a bit tricky in a more complex proof, and really distracts from the more interesting steps needed to get a proof through. For example, if
twice add1
appears in the body of some other functions, we need to be sure to unfold all those definitions before doing the rewrite.The text was updated successfully, but these errors were encountered: