Denotation of SMT terms for the Strata DSL #
This module interprets the shallowly embedded SMT term language into Lean
types. The interpretation is partial because not every SMT feature is
currently supported. The core entry point is denoteTerm, which builds a
TermDenoteResult describing both the type of a term and a semantic interpreter
for it. The surrounding infrastructure tracks the well-formedness of
term and uninterpreted-function contexts so that evaluation is safe.
The denotation uses propositional extensionality (propext) and
Classical.propDecidable (excluded middle) to make if-then-else over
Prop-valued conditions definable. Downstream correctness proofs
(see FactoryCorrect.lean) inherit these dependencies.
Equations
- mkTypeFunType n = Nat.repeat (fun (x : Type 1) => Type → x) n Type
Instances For
Equations
- applyTypeArg tf α = tf α
Instances For
Equations
- applyTypeArgs tf_2 [] h_2 = tf_2
- applyTypeArgs tf_2 (α :: αs_2) h_2 = applyTypeArgs (applyTypeArg tf_2 α) αs_2 ⋯
Instances For
Equations
- mkNonemptyPred us_2 = Nonempty us_2
- mkNonemptyPred us_2 = ∀ (α : Type), mkNonemptyPred (applyTypeArg us_2 α)
Instances For
Equations
- ⋯ = ⋯
Instances For
- us : Core.SMT.Sort
- usΓ : mkTypeFunType self.us.arity
- nonempty : mkNonemptyPred self.usΓ
Instances For
Equations
Instances For
Instances For
Equations
Instances For
- sΓ : SortEnvironment
- hsΓ : SortEnvironment.WF sctx self.sΓ
Instances For
Equations
- substituteIS iss (Strata.SMT.TermType.prim pty) = Strata.SMT.TermType.prim pty
- substituteIS iss ty_2.option = (substituteIS iss ty_2).option
- substituteIS iss (Strata.SMT.TermType.constr id args) = match Map.find? iss id with | some ty' => ty' | none => Strata.SMT.TermType.constr id (substituteISs iss args)
Instances For
Equations
- substituteISs iss [] = []
- substituteISs iss (ty :: tys_2) = substituteIS iss ty :: substituteISs iss tys_2
Instances For
Equations
- substituteTermVarIS isctx v = { id := v.id, ty := substituteIS isctx v.ty }
Instances For
Equations
- substituteUFIS isctx uf = { id := uf.id, args := List.map (substituteTermVarIS isctx) uf.args, out := substituteIS isctx uf.out }
Instances For
Equations
- One or more equations did not get rendered due to their size.
- substituteTermIS isctx (Strata.SMT.Term.prim v) = Strata.SMT.Term.prim v
- substituteTermIS isctx (Strata.SMT.Term.var v) = Strata.SMT.Term.var (substituteTermVarIS isctx v)
- substituteTermIS isctx (Strata.SMT.Term.none ty) = Strata.SMT.Term.none (substituteIS isctx ty)
- substituteTermIS isctx t_2.some = (substituteTermIS isctx t_2).some
- substituteTermIS isctx (Strata.SMT.Term.app op as ty) = Strata.SMT.Term.app op (substituteTermISs isctx as) (substituteIS isctx ty)
- substituteTermIS isctx (Strata.SMT.Term.quant q vs t_2 b) = Strata.SMT.Term.quant q (List.map (substituteTermVarIS isctx) vs) (substituteTermIS isctx t_2) (substituteTermIS isctx b)
Instances For
Equations
- substituteTermISs isctx [] = []
- substituteTermISs isctx (t :: ts_2) = substituteTermIS isctx t :: substituteTermISs isctx ts_2
Instances For
Equations
- substituteIFIS isctx iF = { uf := substituteUFIS isctx iF.uf, body := substituteTermIS isctx iF.body }
Instances For
Interpret primitive SMT types as Lean types, when supported.
Equations
- denotePrimSort sctx Strata.SMT.TermPrimType.bool = pure fun (x : SortDenoteInput sctx) => Prop
- denotePrimSort sctx Strata.SMT.TermPrimType.int = pure fun (x : SortDenoteInput sctx) => Int
- denotePrimSort sctx (Strata.SMT.TermPrimType.bitvec n) = pure fun (x : SortDenoteInput sctx) => BitVec n
- denotePrimSort sctx Strata.SMT.TermPrimType.real = none
- denotePrimSort sctx Strata.SMT.TermPrimType.string = pure fun (x : SortDenoteInput sctx) => String
- denotePrimSort sctx Strata.SMT.TermPrimType.regex = none
- denotePrimSort sctx Strata.SMT.TermPrimType.trigger = none
Instances For
Interpret an SMT TermType as a Lean Type, when supported.
Returns none when we lack an interpretation (e.g. for reals).
Note: similar to denoteSort, but does not attempt to look up type synonyms.
Equations
- One or more equations did not get rendered due to their size.
- denoteSortAux sctx (Strata.SMT.TermType.prim pty) = denotePrimSort sctx pty
- denoteSortAux sctx ty_2.option = do let ty ← denoteSortAux sctx ty_2 pure fun (sΓ : SortDenoteInput sctx) => Option (ty sΓ)
Instances For
Equations
- denoteSortsAux sctx [] = pure []
- denoteSortsAux sctx (a :: as) = do let a ← denoteSortAux sctx a let as ← denoteSortsAux sctx as pure (a :: as)
Instances For
Interpret an SMT TermType as a Lean Type, when supported.
Returns none when we lack an interpretation (e.g. for reals).
Equations
- One or more equations did not get rendered due to their size.
- denoteSort sctx (Strata.SMT.TermType.prim pty) = denotePrimSort sctx pty
- denoteSort sctx ty_2.option = do let ty ← denoteSort sctx ty_2 pure fun (sΓ : SortDenoteInput sctx) => Option (ty sΓ)
Instances For
Equations
- denoteSorts sctx [] = pure []
- denoteSorts sctx (a :: as) = do let a ← denoteSort sctx a let as ← denoteSorts sctx as pure (a :: as)
Instances For
Interpret a function type described by SMT term variables and a return type.
The result is an arrow type a₁ → … → out when every argument and the
result type can be interpreted.
Equations
- denoteFunSort sctx [] out = denoteSort sctx out
- denoteFunSort sctx (a :: as_2) out = do let a ← denoteSort sctx a.ty let as ← denoteFunSort sctx as_2 out pure fun (sΓ : SortDenoteInput sctx) => a sΓ → as sΓ
Instances For
Runtime value paired with a term-variable declaration and a proof that the type can be interpreted.
- var : Strata.SMT.TermVar
- varΓ : (denoteSort sctx self.var.ty).get ⋯ sΓ
Instances For
Equations
Instances For
Forget semantic values, keeping only the declared term variables.
Equations
- tΓ.toContext = List.map (fun (x : TermVarDenote sΓ) => x.var) tΓ
Instances For
Well-formedness predicate ensuring that an interpreted term-variable environment matches its syntactic context.
Instances For
Runtime function paired with the corresponding uninterpreted-function declaration and interpretation witness.
- uf : Strata.SMT.UF
Instances For
Forget semantic values, keeping only UF declarations.
Instances For
Well-formedness predicate ensuring that an interpreted uninterpreted-function environment aligns with the syntactic declarations.
Instances For
Syntactic context tracking the declared term variables and uninterpreted functions that may appear in a term.
This is intentionally separate from TermEnvironment: an environment contains
strictly more information (semantic values), but denotation judgments are
formulated against syntax-level declarations and then related to environments
via TermEnvironment.WF.
- vs : TermVarContext
- ufs : UFContext
Instances For
Semantic environment providing Lean values for the elements stored in a
TermContext.
Although this could project back to a context (toContext), we keep an
explicit TermContext parameter in denotation APIs so binder-extension and
lookup steps can be stated over declarations first, with realizability tracked
separately via WF.
- vs : TermVarEnvironment sΓ
- ufs : UFEnvironment sΓ
Instances For
Well-formedness predicate linking a semantic Environment with the
corresponding syntactic Context.
- hv : TermVarEnvironment.WF tctx.vs Γ.vs
- huf : UFEnvironment.WF tctx.ufs Γ.ufs
Instances For
Bundle pairing an environment with a proof that it realises a particular context. This is the argument given to semantic interpreters.
- sΓ : SortEnvironment
- hsΓ : SortEnvironment.WF ctx.sctx self.sΓ
- tΓ : TermEnvironment { sΓ := self.sΓ, hsΓ := ⋯ }
- htΓ : TermEnvironment.WF ctx.tctx self.tΓ
Instances For
Result of attempting to interpret a term: carries its type, a proof that the type is supported, and a semantic interpreter.
- ty : Strata.SMT.TermType
- res (tdi : TermDenoteInput ctx) : (denoteSort ctx.sctx self.ty).get ⋯ { sΓ := tdi.sΓ, hsΓ := ⋯ }
Instances For
Check that denoted argument types match declared variable types.
If lengths differ, this returns false.
Equations
- argTypesAlign [] [] = true
- argTypesAlign (a :: as_2) (v :: vs_2) = (a.ty == v.ty && argTypesAlign as_2 vs_2)
- argTypesAlign as vs = false
Instances For
Apply the semantic interpretation of a UF symbol to denoted arguments.
Equations
- applyUFAux tdi uf_2 [] hl_2 has_2 = uf_2
- applyUFAux tdi uf_2 (a :: as_2) hl_2 has_2 = applyUFAux tdi ((⋯ ▸ uf_2) (⋯ ▸ a.res tdi)) as_2 ⋯ ⋯
Instances For
Apply the semantic interpretation of a UF symbol to denoted arguments.
Equations
- applyUF tdi uf as hAlign = applyUFAux tdi uf as ⋯ ⋯
Instances For
Shape of a one-variable quantifier binder combinator (∀ or ∃).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Semantics helper for universal quantification.
Given a body interpretation over the context extended with one bound variable
(n : ty), produce the interpretation in the original context by universally
quantifying over all Lean values of the denoted sort ty. This also extends
the term environment with the chosen value and carries the corresponding WF
proof for the extended context.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Semantics helper for existential quantification.
Given a body interpretation over the context extended with one bound variable
(n : ty), produce the interpretation in the original context by existentially
quantifying over Lean values of the denoted sort ty. This also extends the
term environment with the chosen witness and carries the corresponding WF
proof for the extended context.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
- buildQuant bindVar ctx [] hTys_2 bodyFt_2 tdi = bodyFt_2 tdi
Instances For
Equations
- buildExists ctx vs hTys bodyFt tdi = buildQuant (fun {n : String} {ty : Strata.SMT.TermType} => bindExistsVar) ctx vs hTys bodyFt tdi
Instances For
Equations
- buildForall ctx vs hTys bodyFt tdi = buildQuant (fun {n : String} {ty : Strata.SMT.TermType} => bindForallVar) ctx vs hTys bodyFt tdi
Instances For
Attempt to interpret a single SMT term under ctx, returning its Lean type
and semantics when successful.
Instances For
Interpret every term in a list, short-circuiting if any sub-term fails.
Equations
- denoteTerms ctx [] = pure []
- denoteTerms ctx (a :: as) = do let a ← denoteTerm ctx a let as ← denoteTerms ctx as pure (a :: as)
Instances For
Equations
Instances For
Equations
Instances For
Equations
- rightAssoc ctx ty h op ts = do let ft ← rightAssoc.go ctx ty h op ts pure { ty := ty, h := h, res := ft }
Instances For
Equations
- One or more equations did not get rendered due to their size.
- rightAssoc.go ctx ty h op [] = none
- rightAssoc.go ctx ty h op [head] = none
Instances For
Equations
Instances For
Equations
- One or more equations did not get rendered due to their size.
- chainable.go ctx ty h op ft ft₁ [] = pure { ty := Strata.SMT.TermType.prim Strata.SMT.TermPrimType.bool, h := ⋯, res := ft }
Instances For
Interpret a ground boolean term in the empty context.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Interpret a ground integer term in the empty context.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Interpret a ground bitvector term in the empty context.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Interpret a ground string term in the empty context.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Eliminate one uninterpreted sort binder by quantifying over all of its semantic realizations and extending the sort environment accordingly.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Extend the context with an uninterpreted function and push its realisation into the denotation.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Lambda-lift one IF-body argument binder into an arrow in the resulting function.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Turn a denoted IF body (under its argument binders) into a denoted function.
Equations
- One or more equations did not get rendered due to their size.
- buildIFBody ctx bodyFt_2 tdi = bodyFt_2 tdi
Instances For
Eliminate one interpreted-function declaration from the term context.
ft' expects a context where the function symbol (n : args -> out) is
available in tctx.ufs. This combinator constructs the semantic function by
denoting body, pushes that interpretation into the environment, and returns a
proposition over the original (smaller) context.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Interpret a closed boolean term under SMT declarations.
denoteTerm is context-parametric: it interprets a term relative to explicit
sort/term contexts and semantic environments. This function "closes" that
interpretation by successively eliminating context binders (IF, UF, sort
aliases, uninterpreted sorts) and then evaluating in the empty environment.
It is boolean-specific because SMT queries denote propositions.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- mkISContext iss = mkISContext.go✝ ∅ iss
Instances For
Interpret an SMT query by universally quantifying assumptions and returning the semantic proposition.
Equations
- One or more equations did not get rendered due to their size.