clash-lib
Copyright(C) 2026 QBayLogic B.V.
LicenseBSD2 (see the file LICENSE)
MaintainerQBayLogic B.V. <devops@qbaylogic.com>
Safe HaskellSafe-Inferred
LanguageHaskell2010

Clash.Rewrite.StrategyDSL

Description

A pure description language for rewrite strategies. A strategy written in this DSL is compiled by Clash.Rewrite.StrategyDSL.TH into a fused traversal that matches each node's constructor once and runs only the transformations registered for that constructor.

The DSL has two layers:

  • Step: what runs at a single node inside a fused traversal. An ordered chain of transformations, sequencing and success/failure conditionals between chain segments, or a whole nested strategy embedded as one node action.
  • Strat: a complete strategy. Fused traversals over a Step, whole-term passes, and the usual combinators (>->, !->, >-!, >-!->, repeatR) between them.
Synopsis

Transformation metadata

data Constructor Source #

One Term constructor.

data TransformationWorker Source #

A single function separated by the constructor it fires on. Note that this isn't a single transformation per se, as one transformation might fire on multiple constructors. Transformation ties together multiple workers into a single transformation.

The Name must refer to an exported top-level worker so the generated dispatch code can reference it from the splice site.

A worker that returns a term other than the one it was given must say so with changed: a chain hands the fields it matched to the next member as long as no change was signaled.

Constructors

FieldWorker !Constructor !Name

worker :: TransformContext -> Term -> <fields of the constructor> -> RewriteMonad extra Term. The worker receives the matched node (to return on the unchanged path with sharing intact) followed by the constructor's fields.

Worker !Constructor !Name

worker :: Rewrite extra. A worker that fires only at the given constructor, like the per-constructor worker above, but receives the whole node instead of its deconstructed fields. For transformations that decompose the node themselves, e.g. by collecting the entire application spine rather than one App layer.

AnyWorker !Name

worker :: Rewrite extra, applied at all constructors. For a transformation whose firing condition lives in the TransformContext rather than the constructor (topLet).

data Transformation Source #

Single, named transformation. Can consist of multiple workers (see TransformationWorker).

Constructors

Transformation 

Fields

toTransformation :: String -> [TransformationWorker] -> Transformation Source #

Declare a transformation's workers: at most one per constructor, and either an AnyWorker or per-constructor workers, never both. Checked when the transformation is compiled.

anyConstructor :: String -> Name -> Transformation Source #

Declare a transformation that fires at any constructor. See AnyWorker.

named :: String -> Transformation -> Transformation Source #

Give a transformation a different name; used for deliberate debug aliases of a transformation that runs at several strategy positions (the transformation counters and rewrite history key on the name).

Worker builders: workers receiving the constructor's fields

Worker builders: workers receiving the node itself

Node layer

data Step Source #

What runs at a single node inside a fused traversal.

Constructors

Chain [Transformation]

One constructor match dispatches the members registered for that constructor, in list order. Equivalent to the sequential apply n1 t1 >-> apply n2 t2 … chain over all members.

SeqS Step Step

>-> at the node: the right side re-dispatches on the left side's result.

OnChangeS Step Step

!-> at the node: the right side runs only when the left side signaled change.

OnNoChangeS Step Step

>-! at the node: the right side runs only when the left side did not signal change.

EmbedS Strat

A whole strategy as one node action.

Instances

Instances details
Show Step Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL

Methods

showsPrec :: Int -> Step -> ShowS #

show :: Step -> String #

showList :: [Step] -> ShowS #

Strategic Step Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL

Methods

(>->) :: Step -> Step -> Step Source #

(!->) :: Step -> Step -> Step Source #

(>-!) :: Step -> Step -> Step Source #

ToStep Step Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL

Methods

toStep :: Step -> Step Source #

Eq Step Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL

Methods

(==) :: Step -> Step -> Bool #

(/=) :: Step -> Step -> Bool #

chain :: [Transformation] -> Step Source #

An ordered chain of transformations, dispatched per constructor. See Chain.

one :: Transformation -> Step Source #

A singleton chain, for use as an operand of the node-level operators.

nested :: Strat -> Step Source #

Embed a whole strategy as a single node action.

Strategy layer

data Strat Source #

A complete rewriting strategy.

Constructors

TopDown Step

Fused topdownR: repeat the step at each node until it no longer fires, then descend.

BottomUp Step

Fused bottomupR: descend first, run the step once on the rebuilt node.

TopDownFix Step

Fused topdownFixR. Mind its soundness precondition (Note [topdownFixR] in Clash.Rewrite.Combinators).

TopDownSuc Step

Fused topdownSucR: stop at the first success, neither repeating nor descending below it.

InnerMost Step

Fused innerMost: bottom-up; when the step fires, re-traverse the result until the innermost fixpoint is reached.

Pass String Name

A whole-term pass: apply <name> <rewrite>, for transformations that traverse the term themselves (makeANF, etaExpansionTL, …).

CallStrategy Name

Reference to another compiled strategy binding.

Seq Strat Strat

>->

DeepSeqS Strat Strat

>-!->

OnChange Strat Strat

!->

OnNoChange Strat Strat

>-!

Repeat Strat

repeatR

Instances

Instances details
Show Strat Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL

Methods

showsPrec :: Int -> Strat -> ShowS #

show :: Strat -> String #

showList :: [Strat] -> ShowS #

Strategic Strat Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL

Eq Strat Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL

Methods

(==) :: Strat -> Strat -> Bool #

(/=) :: Strat -> Strat -> Bool #

topdown :: ToStep s => s -> Strat Source #

pass :: String -> Name -> Strat Source #

A whole-term pass, run as apply <name> <rewrite>.

callStrategy :: Name -> Strat Source #

Reference another compiled strategy by the name of its binding.

repeatR :: Strat -> Strat Source #

Keep applying a strategy until it no longer fires.

Combinators

class Strategic a where Source #

The combinators shared by both DSL layers. Fixities match Clash.Rewrite.Combinators; a strategy spec module should import only this module, so the names are unambiguous there.

Methods

(>->) :: a -> a -> a infixr 6 Source #

Apply two strategies in succession.

(!->) :: a -> a -> a infixr 5 Source #

Only apply the second strategy if the first one succeeds.

(>-!) :: a -> a -> a infixr 5 Source #

Only apply the second strategy if the first one fails.

Instances

Instances details
Strategic Step Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL

Methods

(>->) :: Step -> Step -> Step Source #

(!->) :: Step -> Step -> Step Source #

(>-!) :: Step -> Step -> Step Source #

Strategic Strat Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL

(>-!->) :: Strat -> Strat -> Strat infixr 6 Source #

Apply two strategies in succession, with a deepseq of the term in between. Strategy layer only.

class ToStep s where Source #

Things that can be used where a Step is expected; a bare Transformation lifts to a singleton chain.

Methods

toStep :: s -> Step Source #

Instances

Instances details
ToStep Step Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL

Methods

toStep :: Step -> Step Source #

ToStep Transformation Source # 
Instance details

Defined in Clash.Rewrite.StrategyDSL