-
Notifications
You must be signed in to change notification settings - Fork 11
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
Work Variables #87
Comments
The proof checker itself does not need those, and it shall not be impacted. I see two possible approaches:
Note that for each work variable, we would possibly need two new Atoms:
In both cases, it would not be possible to associate a |
I think we should not use |
Thanks for your quick feedback! Though, I believe that once one has a parse tree for all formulas in the database, proof verification might possibly be sped up significantly, since a substitution can be performed in constant time, and best-case comparison of different formula is also constant time if the parse tree root differs. That was part of my project in the somewhat orphaned #63 : building an abstract proof verification, which could be used both on textual representation of expressions (like currently), or on formulas, or any other support. I'll give it some thought, as it sounds like the best way to implement this is inheritance and overriding, but rust usually forces to think differently: here, Formula would typically become a |
If you do have a type for this, you should not mix constants, variables and metavariables. From a proof assistant's perspective, variables act like constants and metavariables act like variables, because only the latter are subject to substitution. The distinction between constants and variables still matters however, because disjoint variable requirements are expressed in terms of the variables contained in the expression (and you need to have some higher order thing in order to handle disjoint variable requirements for unresolved metavariables properly; mmj2 just defers the check until the metavariable is completely assigned). Regarding "inheritance", I would just have a match x {
Formula::Const(x) => MetaFormula::Const(x),
Formula::Var(x) => MetaFormula::Var(x),
} where |
Indeed, interesting.
With
Where
I've been using the metamath-knife |
MMj2 represents formulas as trees of statements (the parse tree), and work variables are As another point of comparison, in MM0 expressions are represented completely differently in the proof assistant and in the packed version in the environment. The latter is an |
Regarding your last edit: metavariables are allocated and their assignments tracked by the proof context (global to the whole proof, not just the one expression). So there is no need for a |
Sorry this was misleading, of course metavariables shall be tracked at the level of the proof context. What I meant there was a kind of boolean flag to indicate where in the subtrees there are metavariables, as a kind of local cache/speedup, quite like you explain in your last sentence. |
If I remember correctly, MM0 has a very rich Lisp syntax which includes not just expressions and metavariables, but also instructions/commands. I assume that this is what |
Yes, The grammar of allowed expressions looks something like this, which you should think of as a subset of enum MetaFormula {
Atom(AtomId), // variable/hypothesis reference
List(AtomId, Vec<MetaFormula>), // term/theorem application
MVar(MVarId), // term metavariable
Goal(GoalId), // proof metavariable
} So yes, it is a tree structure, with explicit variants for metavariables. (There is also a bit more than this, for Here is the actual code that does the parsing of |
Note that in this kind of setup, metavariables can end up hanging around in the term even after they have been assigned, because there is no explicit list of all expressions everywhere which we can iterate over to eliminate all occurrences of the metavariable. (And even if there was, this would be quite expensive when you are creating and assigning lots of short-lived metavariables.) Instead, you just remember that the metavariable is assigned, and make sure that anything you do with expressions treats assigned metavariables as equivalent to the expression that they were assigned to. |
This is the method I'd like to use. There will still be another layer of meta variables on top of that (like Nevertheless, the work variables / metavariables are not evaluated, but are to be resolved through unification - just the one that metamath-knife shall provide. It looks to me like the best way to do that would be to use a generic data type |
This would be great! I find work variables quite helpful. I'm currently slammed on other things, but I'm hoping to become more present for Metamath stuff in the nearer future. Until then, if I'm a blocker for something let me know, I do not want to inhibit the awesome stuff everyone else is doing. |
So PR #89 is a proposal to introduce support for work variables, whereas they are supplied externally as suggested by Mario. |
In MMJ2, whenever applying a theorem leaves unresolved substitutions, like when applying
~addcan2ad
in the example below, work variables such as&C1
are created.Coq calls them existential variables, and it looks like Lean calls them metavariables.
It would be nice if
metamath-knife
could support this functionality.The text was updated successfully, but these errors were encountered: