Rewrite rules are represented as nested monads: a `Rule`

is a `Pattern`

that returns a `Rewrite`

the latter directly defining the transformation of the graph.

For rule construction a few functions a provided: The most basic one is `rewrite`

. But in most cases `erase`

, `rewire`

, and 'replace*' should be more convenient. These functions express rewrites that *replace* the matched nodes of the `Pattern`

, which comes quite close to the `L -> R`

form in which graph rewriting rules are usually expressed.

- type Rule n = Pattern n (Rewrite n ())
- apply :: Rule n -> Rewrite n ()
- rewrite :: (Match -> Rewrite n a) -> Rule n
- erase :: View [Port] n => Rule n
- rewire :: View [Port] n => [[Edge]] -> Rule n
- data RHS v
- replace :: (View [Port] n, View v n) => Int -> ([Edge] -> [RHS v]) -> Rule n
- (>>>) :: Rule n -> Rule n -> Rule n
- exhaustive :: Rule n -> Rule n
- everywhere :: Rule n -> Rule n

# Documentation

rewrite :: (Match -> Rewrite n a) -> Rule nSource

primitive rule construction with the matched nodes of the left hand side as a parameter

erase :: View [Port] n => Rule nSource

constructs a rule that deletes all of the matched nodes from the graph

rewire :: View [Port] n => [[Edge]] -> Rule nSource

Constructs a rule from a list of rewirings. Each rewiring specifies a list of hyperedges that are to be merged into a single hyperedge. All matched nodes of the left-hand side are removed.

replace :: (View [Port] n, View v n) => Int -> ([Edge] -> [RHS v]) -> Rule nSource

Constructs a rule that replaces the matched nodes of the left-hand side by new nodes and rewirings. It generates an amount of new edges specified by the `Int`

. In most cases the functions below named `replace*`

should be sufficient.

(>>>) :: Rule n -> Rule n -> Rule nSource

Replaces the matched nodes by a list of new nodes and rewirings.

Replaces the matched nodes by a list of new nodes and rewirings. It also generates one new edge.

Replaces the matched nodes by a list of new nodes and rewirings. It also generates two new edges.

You get the idea.

Apply two rules consecutively. Second rule is only applied if first one succeeds. Fails if (and only if) first rule fails.

exhaustive :: Rule n -> Rule nSource

Make a rule exhaustive, i.e. such that (when applied) it reduces redexes until no redexes are occur in the graph.

everywhere :: Rule n -> Rule nSource

Make a rule parallel, i.e. such that (when applied) all current redexes are contracted one by one. Neither new redexes or destroyed redexes are reduced.