NOTE: Monadic Code Needs Pointfree Theorems #
It is always best to write theorems in unapplied fashion, since a monadic function is often used in chains of binds.
A theorem of the form 'f1 x = f2 x'cannot be used in a context 'f1 >>= g', but a pointfree theorem of the form 'f = g'permits rewriting everywhere, even in 'f1 >>= g'.
This is not a problem in pure code, since we rarely use poinfree style with (f ∘ g), but this is much more pervasive in monadic code, where 'f >>= g' is common.
Thus, the rule is that ALL rewrite rules are written pointfree in the last argument.
NOTE: Normal form for monadic code #
We never use functor and applicative instances. Rather, we always write definitions in terms of monadic code, using 'non-canonical' haskell code such as mv >>= (fun v => return (g v)) rather than writing the more natural g <$> mv since it is much easier to design simp sets and tactics that consistenty simplify monadic bind, instead of a combination of: <$>, <*>, return, pure, >>=.
Furthermore, consistent use of >>= simplifes reasoning about information flow, where left-to-right order clearly implies the direction of information flow.
- mkEffectful :: (
- sig : List Ty
- regSig : RegionSignature Ty
- outTy : Ty
- effectKind : EffectKind
- )
Instances For
Equations
- Signature.mk sig regSig outTy = { sig := sig, regSig := regSig, outTy := outTy, effectKind := EffectKind.pure }
Instances For
Instances For
Instances For
Instances For
Instances For
- denote : (op : d.Op) → HVector TyDenote.toType (DialectSignature.sig op) → HVector (fun (t : Ctxt d.Ty × d.Ty) => t.1.Valuation → EffectKind.impure.toMonad d.m ⟦t.2⟧) (DialectSignature.regSig op) → (DialectSignature.effectKind op).toMonad d.m ⟦DialectSignature.outTy op⟧
Instances
An intrinsically typed expression whose effect is at most EffectKind
- mk: {d : Dialect} → [inst : DialectSignature d] → {eff : EffectKind} → {Γ : Ctxt d.Ty} → {ty : d.Ty} → (op : d.Op) → ty = DialectSignature.outTy op → DialectSignature.effectKind op ≤ eff → HVector Γ.Var (DialectSignature.sig op) → HVector (fun (t : Ctxt d.Ty × d.Ty) => Com d t.1 EffectKind.impure t.2) (DialectSignature.regSig op) → Expr d Γ eff ty
Instances For
A very simple intrinsically typed program: a sequence of let bindings.
Note that the EffectKind
is uniform: if a Com
is pure
, then the expression
and its body are pure, and if a Com
is impure
, then both the expression and
the body are impure!
- ret: {d : Dialect} → [inst : DialectSignature d] → {Γ : Ctxt d.Ty} → {t : d.Ty} → {eff : EffectKind} → Γ.Var t → Com d Γ eff t
- var: {d : Dialect} → [inst : DialectSignature d] → {Γ : Ctxt d.Ty} → {eff : EffectKind} → {α β : d.Ty} → Expr d Γ eff α → Com d (Γ.snoc α) eff β → Com d Γ eff β
Instances For
Lets d Γ_in Γ_out
is a sequence of lets which are well-formed under
context Γ_out
and result in context Γ_in
.
- nil: {d : Dialect} → [inst : DialectSignature d] → {Γ_in : Ctxt d.Ty} → {eff : EffectKind} → Lets d Γ_in eff Γ_in
- var: {d : Dialect} → [inst : DialectSignature d] → {Γ_in : Ctxt d.Ty} → {eff : EffectKind} → {Γ_out : Ctxt d.Ty} → {t : d.Ty} → Lets d Γ_in eff Γ_out → Expr d Γ_out eff t → Lets d Γ_in eff (Γ_out.snoc t)
Instances For
Zipper d Γ_in eff Γ_mid ty
represents a particular position in a program, by storing the
Lets
that come before this position separately from the Com
that represents the rest.
Thus, Γ_in
is the context of the program as a whole, while Γ_mid
is the context at the
current position.
While technically the position is in between two let-bindings, by convention we say that the first
binding of top : Lets ..
is the current binding of a particular zipper.
- top : Lets d Γ_in eff Γ_mid
The let-bindings at the top of the zipper
- bot : Com d Γ_mid eff ty
The program at the bottom of the zipper
Instances For
Convert a HVector of region arguments into a List of format strings.
Format string for a Com, with the region parentheses and formal argument list.
Format string for sequence of assignments and return in a Com.
Equations
- Lets.repr prec Lets.nil = Lean.Format.align false ++ Lean.format ";"
- Lets.repr prec (body.var e) = Lets.repr prec body ++ (Lean.Format.align false ++ (Lean.format "" ++ Lean.format (Expr.repr prec e) ++ Lean.format ""))
Instances For
Equations
- One or more equations did not get rendered due to their size.
Equations
- One or more equations did not get rendered due to their size.
- Com.recAux' ret var (Com.ret v) = ret v
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Alternative recursion principle for known-pure Com
s
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.
Instances For
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.
Instances For
Projection equations for Expr
The size of a Com
is given by the number of let-bindings it contains
Equations
- One or more equations did not get rendered due to their size.
Instances For
The outContext
of a program is a context which includes variables for all let-bindings
of the program. That is, it is the context under which the return value is typed
Equations
- One or more equations did not get rendered due to their size.
Instances For
The difference between the context Γ
under which com
is typed, and the output context of
that same com
Equations
- com.outContextDiff = ⟨com.size, ⋯⟩
Instances For
com.outContextHom
is the canonical homorphism from free variables of com
to those same
variables in the output context of com
Equations
- com.outContextHom = com.outContextDiff.toHom
Instances For
The return variable of a program
Instances For
Add a Com
to the end of a sequence of lets
Equations
Instances For
The let-bindings of a program
Equations
- com.toLets = Lets.nil.addComToEnd com
Instances For
Instances For
Equations
- (Expr.mk op ⋯ heff args regArgs).denote Γv = EffectKind.liftEffect heff (DialectDenote.denote op (HVector.map (fun (x : d.Ty) (v : Γ.Var x) => Γv v) args) regArgs.denote)
Instances For
Equations
Instances For
Denote just the let bindings of com
, transforming a valuation for Γ
into a valuation for
the output context of com
Equations
Instances For
Denote an Expr
in an unconditionally impure fashion
Instances For
Denote a Com
in an unconditionally impure fashion
Equations
Instances For
Equations
Instances For
denotePure
is a specialization of denote
for pure Lets
.
Theorems and definitions should always be phrased in terms of the latter.
However, denotePure
behaves slighly better when it comes to congruences, since congr
does not
realize that pure.toMonad d.m (Valuation _)
is just Valuation _
, and thus a function.
Therefore, if a goalstate is ⊢ lets.denote ... = lets.denote ...
, and lets
is pure, then to use
the congruence, you can do: rw [← Lets.denotePure]; congr
Equations
- Lets.denotePure = Lets.denote
Instances For
Denote a Lets
in an unconditionally impure fashion
Equations
Instances For
The denotation of a zipper is a composition of the denotations of the constituent
Lets
and Com
Instances For
Equation lemma to unfold denote
, which does not unfold correctly due to the presence
of the coercion ty_eq
and the mutual definition.
simp-lemmas about denote
functions
changeVars
#
Map a context homomorphism over a Expr
/Com
.
That is, substitute variables.
Equations
- Expr.changeVars varsMap (Expr.mk op sig_eq eff_leq args regArgs) = Expr.mk op sig_eq eff_leq (HVector.map varsMap args) regArgs
Instances For
Equations
Instances For
simp-lemmas about changeVars
Equations
- Com.outContext_changeVars_hom map_inv = cast ⋯ map_inv
- Com.outContext_changeVars_hom map_inv = cast ⋯ (Com.outContext_changeVars_hom map_inv.snocMap)
Instances For
FlatCom Γ eff Δ ty
represents a program as a sequence Lets Γ eff Δ
and a Var Δ ty
.
This is isomorphic to Com Γ eff ty
, where Δ
is com.outContext
- lets : Lets d Γ_in eff Γ_out
- ret : Γ_out.Var ty
Instances For
Denote the Lets of the FlatICom
Equations
- flatCom.denoteLets Γv = flatCom.lets.denote Γv
Instances For
Denote the lets and the ret of the FlatCom. This is equal to denoting the Com
Instances For
casting of expressions and purity #
Change the effect of an expression into another effect that is "higher" in the hierarchy. Generally used to change a pure expression into an impure one, but it is useful to have this phrased more generically
Equations
- Expr.changeEffect h (Expr.mk op ty_eq eff_le args regArgs) = Expr.mk op ty_eq ⋯ args regArgs
Instances For
Change the effect of a program into another effect that is "higher" in the hierarchy. Generally used to change a pure program into an impure one, but it is useful to have this phrased more generically
Equations
- One or more equations did not get rendered due to their size.
Instances For
Change the effect of a sequence of lets into another effect that is "higher" in the hierarchy. Generally used to change pure into impure, but it is useful to have this phrased more generically
Instances For
cast a pure Expr into a possibly impure expression
Equations
Instances For
Equations
Instances For
Equations
- Lets.castPureToEff eff Lets.nil = Lets.nil
- Lets.castPureToEff eff (body.var e) = (Lets.castPureToEff eff body).var (Expr.castPureToEff eff e)
Instances For
A wrapper around Com.var
that allows for a pure expression to be added to an otherwise
impure program, using Expr.castPureToEff
Equations
- Com.letPure e body = Com.var (Expr.castPureToEff eff e) body
Instances For
letSup e body
allows us to combine an expression and body with different effects,
by returning a Com
whose effect is their join/supremum
Equations
- Com.letSup e body = Com.var (Expr.changeEffect ⋯ e) (Com.changeEffect ⋯ body)
Instances For
castPureToEff
does not change the size of a Com
denotations of castPureToEff
Whether the operation of an expression is pure (which might be evaluated impurely)
Equations
- e.HasPureOp = (DialectSignature.effectKind e.op = EffectKind.pure)
Instances For
e.HasPureOp
is decidable
Equations
Attempt to convert a possibly impure expression into a pure expression.
If the expression's operation is impure, return none
Equations
- (Expr.mk op ty_eq eff_le args regArgs).toPure? = match h : DialectSignature.effectKind op with | EffectKind.pure => some (Expr.mk op ty_eq ⋯ args regArgs) | EffectKind.impure => none
Instances For
The operation of a pure expression is necessarily pure
Rewrite theorem for an expression with a pure operation (which might be evaluated impurely)
casting an expr to an impure expr and running it equals running it purely and returning the value
The denotation of toPure?
Equations
- com.toFlatCom = { lets := com.toLets, ret := com.returnVar }
Instances For
Recombine a zipper into a single program by adding the lets
to the beginning of the com
Equations
- zip.toCom = Zipper.toCom.go zip.top zip.bot
Instances For
Equations
- Zipper.toCom.go Lets.nil com = com
- Zipper.toCom.go (body.var e) com = Zipper.toCom.go body (Com.var e com)
Instances For
Add a Com
directly before the current position of a zipper, while reassigning every
occurence of a given free variable (v
) of zip.com
to the output of the new Com
Equations
- zip.insertCom v newCom = { top := zip.top.addComToEnd newCom, bot := zip.bot.changeVars (newCom.outContextHom.with v newCom.returnVar) }
Instances For
Add a pure Com
directly before the current position of a possibly impure
zipper, while r eassigning every occurence of a given free variable (v
) of
zip.com
to the output of the new Com
This is a wrapper around insertCom
(which expects newCom
to have the same effect as zip
)
and castPureToEff
Equations
- zip.insertPureCom v newCom = ⋯ ▸ zip.insertCom v (Com.castPureToEff eff newCom)
Instances For
simp-lemmas
Casting the intermediate context is not relevant for the denotation
Semantic preservation of Zipper.insertPureCom
#
Generally, we don't intend for insertPureCom
to change the semantics of the zipper'd program.
We characterize the condition for this intended property by proving denote_insertPureCom_eq_of
,
which states that if the reassigned variable v
in the original top
of the zipper is semantically
equivalent to the return value of the inserted program newCom
, then the denotation of the zipper
after insertion agrees with the original zipper.
Denoting any of the free variables of a program through Com.denoteLets
just returns the
assignment of that variable in the input valuation
Inserting multiple programs with Zipper.foldInsert
#
Random Access for Lets
#
Get the let-binding that correponds to a given variable v
,
so long as the binding's operation is pure
Get the Expr
that a var v
is assigned to in a sequence of Lets
,
without adjusting variables, assuming that this expression has a pure operation.
If the expression has an impure operation, or there is no binding corresponding to v
(i.e., v
comes from Γ_in
), return none
Equations
- One or more equations did not get rendered due to their size.
- Lets.nil.getPureExprAux x_2 = none
Instances For
Get the Expr
that a var v
is assigned to in a sequence of Lets
.
The variables are adjusted so that they are variables in the output context of a lets,
not the local context where the variable appears.
Equations
- lets.getPureExpr v = Expr.changeVars Ctxt.dropUntilHom <$> lets.getPureExprAux v
Instances For
Mapping #
We can map between different dialects
Equations
Instances For
Equations
- instFunctorRegionSignature = { map := fun {α β : Type} => RegionSignature.map, mapConst := fun {α β : Type} => RegionSignature.map ∘ Function.const β }
Equations
- Signature.map f sig = { sig := List.map f sig.sig, regSig := RegionSignature.map f sig.regSig, outTy := f sig.outTy, effectKind := EffectKind.pure }
Instances For
Equations
- One or more equations did not get rendered due to their size.
A dialect morphism consists of a map between operations and a map between types, such that the signature of operations is respected
- mapOp : d.Op → d'.Op
- mapTy : d.Ty → d'.Ty
Instances For
Equations
- ⋯ = ⋯
Instances For
Equations
- ⋯ = ⋯
Instances For
Equations
- ⋯ = ⋯
Instances For
Equations
- Com.changeDialect f (Com.ret v) = Com.ret v.toMap
- Com.changeDialect f (Com.var e body) = Com.var (Expr.changeDialect f e) (Com.changeDialect f body)
Instances For
Equations
- Expr.changeDialect f (Expr.mk op ⋯ heff args regArgs) = Expr.mk (f.mapOp op) ⋯ ⋯ (⋯ ▸ HVector.map' f.mapTy (fun (x : d.Ty) => Ctxt.Var.toMap) args) (⋯ ▸ HVector.changeDialect f regArgs)
Instances For
Inline of HVector.map'
for the termination checker
Equations
- HVector.changeDialect f HVector.nil = HVector.nil
- HVector.changeDialect f (a::ₕas) = (Com.changeDialect f a::ₕHVector.changeDialect f as)
Instances For
Equations
- Lets.changeDialect f Lets.nil = Lets.nil
- Lets.changeDialect f (body.var e) = (Lets.changeDialect f body).var (Expr.changeDialect f e)
Instances For
Mapping #
Free Variables #
Equations
- T.vars = HVector.foldl (fun (x : d.Ty) (s : Γ.VarSet) (a : Γ.Var x) => insert ⟨x, a⟩ s) ∅ T
Instances For
The free variables of lets
that are (transitively) referred to by some variable v
.
Also known as the uses of var.
Equations
- One or more equations did not get rendered due to their size.
- Lets.nil.vars v = Ctxt.VarSet.ofVar v
Instances For
com.vars
is the set of free variables from Γ
that are (transitively) used by the return
variable of com
Equations
- com.vars = com.toFlatCom.lets.vars com.toFlatCom.ret
Instances For
For a vector of variables T, let s₁ and s₂ be two maps from variables to A t. If s₁ and s₂ agree on all variables in T (which is a VarSet), then T.map s₁ = T.map s₂
Expression Trees #
Morally, a pure Com
can be represented as just a tree of expressions.
We use this intuition to explain what matchVar
does, but first we give a semi-formal definition
of ExprTree
and its operations.
A tree of pure expressions
- mk: {d : Dialect} → [inst : DialectSignature d] → {Γ : Ctxt d.Ty} → {ty : d.Ty} → (op : d.Op) → ty = DialectSignature.outTy op → DialectSignature.effectKind op = EffectKind.pure → ExprTreeBranches d Γ (DialectSignature.sig op) → ExprTree d Γ ty
- fvar: {d : Dialect} → [inst : DialectSignature d] → {Γ : Ctxt d.Ty} → {ty : d.Ty} → Γ.Var ty → ExprTree d Γ ty
Instances For
- nil: {d : Dialect} → [inst : DialectSignature d] → {Γ : Ctxt d.Ty} → ExprTreeBranches d Γ []
- cons: {d : Dialect} → [inst : DialectSignature d] → {Γ : Ctxt d.Ty} → {t : d.Ty} → {ts : List d.Ty} → ExprTree d Γ t → ExprTreeBranches d Γ ts → ExprTreeBranches d Γ (t :: ts)
Instances For
Equations
- ↑HVector.nil = ExprTreeBranches.nil
- ↑(v::ₕvs) = ExprTreeBranches.cons v ↑vs
Instances For
lets.exprTreeAt v
follows the def-use chain of v
in lets
to produce an ExprTree
whose
free variables are only the free variables of lets
as a whole
Equations
- Lets.nil.exprTreeAt v = ExprTree.fvar v
- (body.var e).exprTreeAt ⟨0, ⋯⟩ = Expr.toExprTree body e
- (body.var e).exprTreeAt ⟨v.succ, h⟩ = body.exprTreeAt ⟨v, h⟩
Instances For
e.toExprTree lets
converts a single expression e
into an expression tree by looking up the
arguments to e
in lets
Equations
- Expr.toExprTree lets e = ExprTree.mk e.op ⋯ ⋯ (Expr.toExprTree.argsToBranches lets e.args)
Instances For
Equations
- Expr.toExprTree.argsToBranches lets HVector.nil = ExprTreeBranches.nil
- Expr.toExprTree.argsToBranches lets (v::ₕvs) = ExprTreeBranches.cons (lets.exprTreeAt v) (Expr.toExprTree.argsToBranches lets vs)
Instances For
TermModel #
We can syntactically give semantics to any dialect by denoting it with ExprTrees
A wrapper around the Ty
universe of a term model, to prevent the instance of TyDenote
leaking to the original type.
- ty : Ty
Instances For
The Term Model of a dialect d
is a dialect with the exact same operations, types, and
signature as the original dialect d
, but whose denotation exists of expression trees.
Equations
- TermModel d _Γ = { Op := d.Op, Ty := TermModelTy d.Ty, m := d.m }
Instances For
- allPure : ∀ (op : d.Op), DialectSignature.effectKind op = EffectKind.pure
Instances
Equations
- instMonadMTermModel = inferInstanceAs (Monad d.m)
Equations
- One or more equations did not get rendered due to their size.
Equations
- instDialectDenoteTermModelOfPureDialect.argsToBranches HVector.nil = ExprTreeBranches.nil
- instDialectDenoteTermModelOfPureDialect.argsToBranches (a_1::ₕas) = ExprTreeBranches.cons a_1 (instDialectDenoteTermModelOfPureDialect.argsToBranches as)
Instances For
A substitution in context Γ
maps variables of Γ
to expression trees in Δ
,
in a type-preserving manner
Equations
- Ctxt.Substitution d Γ Δ = ({ty : d.Ty} → Γ.Var ty → ExprTree d Δ ty)
Instances For
A valuation of the term model w.r.t context Δ
is exactly a substitution
Equations
- ↑V ⟨v, h⟩ = V ⟨v, ⋯⟩
Instances For
A context homomorphism trivially induces a substitution
Equations
- ↑f v = ExprTree.fvar (f v)
Instances For
Equations
- TermModel.morphism = { mapOp := id, mapTy := TermModelTy.mk, preserves_signature := ⋯ }
Instances For
lets.toSubstitution
gives a substitution from each variable in the output context to an
expression tree with variables in the input context by following the def-use chain
Equations
- One or more equations did not get rendered due to their size.
Instances For
e.applySubstitution σ
replaces occurences of v
in e
with σ v
Equations
- ExprTree.applySubstitution σ (ExprTree.fvar v) = σ v
- ExprTree.applySubstitution σ (ExprTree.mk op ⋯ eff_eq args) = ExprTree.mk op ⋯ eff_eq (ExprTreeBranches.applySubstitution (fun {ty : d.Ty} => σ) args)
Instances For
es.applySubstitution σ
maps ExprTree.applySubstution
over es
Equations
- One or more equations did not get rendered due to their size.
- ExprTreeBranches.applySubstitution σ ExprTreeBranches.nil = ExprTreeBranches.nil
Instances For
Matching #
matchArg lets matchLets args matchArgs map
tries to extends the partial substition map
by
calling matchVar lets args[i] matchLets matchArgs[i]
for each pair of corresponding variables,
returning the final partial substiution, or none
on conflicting assigments
Equations
Instances For
matchVar lets v matchLets w map
tries to extend the partial substition map
, such that the
transitive expression trees represented by variables v
and w
become syntactically equal,
returning the final partial substitution map'
on success , or none
on conflicting assignments.
Diagramatically, the contexts are related as follows: Γ_in --[lets]--> Γ_out <--[map]-- Δ_in --[matchLets]--> Δ_out [v] [w]
Informally, we want to find a map
that glues the program matchLets
to the
end of lets
such that the expression tree of v
(in lets
) is syntactically unified with
the expression tree of w
(in matchLets
).
This obeys the hypothetical equation: (matchLets.exprTreeAt w).changeVars map = lets.exprTreeAt v
where exprTreeAt
is a hypothetical definition that gives the expression tree.
NOTE: this only matches on pure let bindings in both matchLets
and lets
.
Equations
Instances For
how matchVar behaves on var
at a successor variable
how matchVar behaves on var
at the last variable.
matchVar only adds new entries:
if matchVar lets v matchLets w ma = .some varMap,
then ma is a subset of varMap.
Said differently, The output mapping of matchVar
extends the input mapping when it succeeds.
e.IsDenotationForPureE Γv x
holds if x
is the pure value obtained from e
under valuation
Γv
, assuming that e
has a pure operation.
If e
has an impure operation, the property holds vacuously.
Equations
Instances For
Equations
Instances For
An alternative version of Lets.denote
, whose returned type carries a proof that the valuation
agrees with the denotation of every pure expression in lets
.
Strongly prefer using Lets.denote
in definitions, but you can use denoteIntoSubtype
in proofs.
The subtype allows us to carry the property with us when doing congruence proofs inside a bind.
Equations
Instances For
if matchVar lets v matchLets w ma = .some varMap, then informally:
Γ_in --⟦lets⟧--> Γ_out --comap ma--> Δ_in --⟦matchLets⟧ --> Δ_out --w--> t = Γ_in ⟦lets⟧ --> Γ_out --v--> t
All variables containing in matchExpr
are assigned by matchVar
.
A version of matchVar
that returns a Hom
of Ctxt
s instead of the AList
,
provided every variable in the context appears as a free variable in matchExpr
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
if matchVarMap lets v matchLets w hvars = .some map, then ⟦lets; matchLets⟧ = ⟦lets⟧(v)
splitProgramAtAux pos lets prog
, will return a Lets
ending
with the pos
th variable in prog
, and an Com
starting with the next variable.
It also returns, the type of this variable and the variable itself as an element
of the output Ctxt
of the returned Lets
.
Equations
- splitProgramAtAux 0 x (Com.var e body) = some ⟨Γ₂.snoc α, (x.var e, body, ⟨α, Ctxt.Var.last Γ₂ α⟩)⟩
- splitProgramAtAux x✝ x (Com.ret v) = none
- splitProgramAtAux n.succ x (Com.var e body) = splitProgramAtAux n (x.var e) body
Instances For
splitProgramAt pos prog
, will return a Lets
ending
with the pos
th variable in prog
, and an Com
starting with the next variable.
It also returns, the type of this variable and the variable itself as an element
of the output Ctxt
of the returned Lets
.
Equations
- splitProgramAt pos prog = splitProgramAtAux pos Lets.nil prog
Instances For
rewriteAt lhs rhs hlhs pos target
, searches for lhs
at position pos
of
target
. If it can match the variables, it inserts rhs
into the program
with the correct assignment of variables, and then replaces occurences
of the variable at position pos
in target
with the output of rhs
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Rewrites are indexed with a concrete list of types, rather than an (erased) context, so that the required variable checks become decidable
- lhs : Com d (↑Γ) EffectKind.pure t
- rhs : Com d (↑Γ) EffectKind.pure t
- correct : self.lhs.denote = self.rhs.denote
Instances For
Equations
- instDecidableForallForallMemSigmaTyVarOfListVarSetVars = decidable_of_iff (∀ (i : Fin Γ.length), let v := ⟨↑i, ⋯⟩; ⟨Γ.get i, v⟩ ∈ lhs.vars) ⋯
Equations
- One or more equations did not get rendered due to their size.
Instances For
rewrite with pr
to target
program, at location ix
and later, running
at most fuel
steps.
Equations
- rewritePeephole_go 0 pr ix target = target
- rewritePeephole_go fuel'.succ pr ix target = rewritePeephole_go fuel' pr (ix + 1) (rewritePeepholeAt pr ix target)
Instances For
rewrite with pr
to target
program, running at most fuel
steps.
Equations
- rewritePeephole fuel pr target = rewritePeephole_go fuel pr 0 target
Instances For
rewritePeephole_go
preserve semantics
rewritePeephole
preserves semantics.
Equations
- One or more equations did not get rendered due to their size.
- rewritePeepholeRecursivelyRegArgs fuel pr HVector.nil = ⟨HVector.nil, ⋯⟩
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
A peephole rewriter that recurses into regions, allowing peephole rewriting into nested code.
Equations
- One or more equations did not get rendered due to their size.
- rewritePeepholeRecursively 0 pr target = ⟨target, ⋯⟩
Instances For
Equations
- x.getTy = d.Ty
Instances For
Equations
- x.ty = t
Instances For
Equations
- x.ctxt = Γ
Instances For
Equations
- x.getTy = d.Ty
Instances For
Equations
- x.ty = t
Instances For
Equations
- x.ctxt = Γ