Repository navigation
Encode a checked sequence operation as its total twin #1483
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: main
Are you sure you want to change the base?
Changes from 13 commits
27f805b
58cffda
898b6ff
500c84a
0daacf2
2277e25
56edc2b
17f5821
bb4860e
eca3749
5e16148
446cb4a
ce5ba56
9a143c5
702a295
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -225,6 +225,32 @@ def lMonoTyToTermType (useArrayTheory : Bool := false) (ty : LMonoTy) : TermType | |
| .constr name (args.map $ lMonoTyToTermType useArrayTheory) | ||
| | .ftvar tv => .constr tv [] | ||
|
|
||
| /-- The total twin of a checked sequence operation. -/ | ||
| private def seqTotalTwin? : String → Option String | ||
| | "Sequence.select" => some "Sequence.select!" | ||
| | "Sequence.update" => some "Sequence.update!" | ||
| | "Sequence.take" => some "Sequence.take!" | ||
| | "Sequence.drop" => some "Sequence.drop!" | ||
| | _ => none | ||
|
|
||
| /-- | ||
| The solver symbol for the function named `name`. | ||
|
|
||
| A checked sequence operation and its total twin denote the same function: they | ||
| differ only in the bounds precondition, which is discharged as a separate | ||
| obligation before encoding. Both are therefore encoded as one symbol, that of | ||
| the total twin, so that a fact stated with either form applies to the other. | ||
| -/ | ||
| private def seqSymbol (name : String) : String := | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (a) This runs on every function the encoder sees and takes the full name apart each time. toSMTOp already has the short name (baseName) a few lines up. Checking that first would skip the work for every op that isn't one of these four. Also, the tys.isEmpty case can't happen, so it could go. (b) This only works because each ! op has the same axioms as its checked twin. Now that they share one solver symbol, only the axioms of whichever form appears first get loaded. If someone later adds an axiom to just one of them, it would be lost or applied to both. Could you add a short note on the four ! definitions in Factory.lean saying their axioms must stay the same as the checked versions? |
||
| match Core.NameMangling.demangleFuncName name with | ||
| | some (base, tys) => | ||
| match seqTotalTwin? base with | ||
| | some twin => | ||
| let stem := Core.NameMangling.monoPrefix ++ Core.NameMangling.monoDelim ++ twin | ||
| if tys.isEmpty then stem else stem ++ Core.NameMangling.monoDelim ++ tys | ||
| | none => name | ||
| | none => (seqTotalTwin? name).getD name | ||
|
|
||
| /-- Convert a datatype's constructors to typed SMT constructors. -/ | ||
| private def datatypeConstructorsToSMT (d : LDatatype CoreLParams.IDMeta) (useArrayTheory : Bool := false): List SMTConstructor := | ||
| d.constrs.map fun c => | ||
|
|
@@ -635,7 +661,7 @@ def toSMTOp (factory : @Lambda.Factory CoreLParams) (fn : CoreIdent) (fnty : LMo | |
| let bvs := formalStrs.zip smt_intys | ||
| let outty := tys.getLast (by exact @LMonoTy.destructArrow_non_empty fnty) | ||
| let (smt_outty, ctx) ← LMonoTy.toSMTType outty ctx | ||
| let uf : UF := { id := (toString $ format fn), args := smt_intys, out := smt_outty } | ||
| let uf : UF := { id := seqSymbol (toString $ format fn), args := smt_intys, out := smt_outty } | ||
| let arrowParams := func.inputs.toList.filter (fun (_, ty) => ty.containsArrow) | ||
| if !arrowParams.isEmpty then | ||
| let names := arrowParams.map (fun (n, _) => toString (format n)) | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add one out-of-range case, e.g. assert Sequence.select(g, 5) == Sequence.select!(g, 5) with length(g) == 2? |
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.
Could this use factory function names instead of brittle strings?