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 Coms
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 Ctxts 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 posth 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 posth 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 = Γ