aboutsummaryrefslogtreecommitdiff
path: root/sucl/rewr.icl
diff options
context:
space:
mode:
Diffstat (limited to 'sucl/rewr.icl')
-rw-r--r--sucl/rewr.icl213
1 files changed, 213 insertions, 0 deletions
diff --git a/sucl/rewr.icl b/sucl/rewr.icl
new file mode 100644
index 0000000..0dc2059
--- /dev/null
+++ b/sucl/rewr.icl
@@ -0,0 +1,213 @@
+implementation module rewr
+
+import rule
+import graph
+import pfun
+import basic
+import StdEnv
+
+/*
+
+Rewriting of graphs
+
+Exported identifiers:
+\begin{description}
+\item[\tt unfold] Apply a rewrite rule to a graph
+\item[\tt xunfold] As {\tt unfold}, but also provides full matching
+ from the applied rule to the (resulting) subject
+ graph
+\item[\tt fold] Apply a rewrite rule in reverse to a graph
+\item[\tt instantiate] Instantiate a graph with a pattern
+\end{description}
+
+Temporarily hidden:
+\begin{description}
+\item[\tt build] Build a copy of a graph
+\end{description}
+
+Temporarily not exported:
+\begin{description}
+\item[\tt getmap] Determine mapping from one graph to another
+\item[\tt existmap] Determine if a mapping from one graph to another exists
+\end{description}
+
+> %export foldfn getmapping instantiate xunfold
+
+ unfold
+ :: pfun *** ** -> || Mapping as result from match of lhs
+ rule * *** -> || Rule to unfold
+ ([**],graph * **,**) -> || Heap,graph,node
+ ([**],graph * **,**) || New heap,graph,node
+
+> xunfold
+> :: ** -> || Root of the redex to unfold
+> rule * *** -> || Rule to unfold by
+> ( [**], || Unused heap
+> **, || Root of subject
+> graph * **, || Subject graph
+> pfun *** ** || Matching of pattern from rule to subject
+> ) ->
+> ( [**], || Remaining heap
+> **, || Possibly redirected root of subject
+> graph * **, || Extended subject graph
+> pfun *** ** || Extended matching from rule to subject
+> )
+
+ fold
+ :: pfun *** ** -> || Mapping as result from match of rhs
+ rule * *** -> || Rule to fold
+ ([**],graph * **,**) -> || Heap,graph,node
+ ([**],graph * **,**) || New heap,graph,node
+
+> build
+> :: graph * *** -> *** -> || Graph,root to be copied
+> ([**],[**],graph * **,pfun *** **) -> || Heap,init nodes,init graph,init mapping
+> ([**],[**],graph * **,pfun *** **) || New heap,new nodes,new graph,new mapping
+
+> getmap :: graph * *** -> *** -> graph * ** -> ** -> pfun *** **
+
+> existmap :: graph * *** -> *** -> graph * ** -> ** -> bool
+
+
+Implementation
+
+> %include "basic.lit"
+> %include "pfun.lit"
+> %include "graph.lit" -instantiate
+> %include "rule.lit"
+
+*/
+
+xunfold
+ :: var
+ (Rule sym pvar)
+ !( [var]
+ , var
+ , Graph sym var
+ , Pfun pvar var
+ )
+ -> ( [var]
+ , var
+ , Graph sym var
+ , Pfun pvar var
+ ) | == var & == pvar
+
+xunfold redexroot rule (heap,root,subject,matching)
+= (heap`,redirection root,redirectgraph redirection subject`,matching`)
+ where (heap`,[rhs`:_],subject`,matching`)
+ = build (rulegraph rule) (ruleroot rule) (heap,[],subject,matching)
+ redirection = adjust redexroot rhs` id
+
+instantiate
+ :: .(Graph sym pvar) // Pattern to instantiate with
+ pvar // Root of the pattern
+ var // Open node to instantiate
+ (.[var],.Graph sym var) // Heap,graph
+ -> .([var],Graph sym var) // New heap,graph
+ | == var
+ & == pvar
+
+instantiate pattern proot node (heap,graph)
+| not closed
+= (heap,graph)
+= (heap``,graph``)
+ where (heap``,params``,graph``,_)
+ = foldr (build pattern) (heap,[],graph`,extend proot node emptypfun) params
+ (closed,(f,params)) = varcontents pattern proot
+ graph` = updategraph node (f,params``) graph
+
+build
+ :: (Graph sym pvar)
+ pvar
+ ( [var]
+ , [var]
+ , Graph sym var
+ , !Pfun pvar var
+ )
+ -> ( [var]
+ , [var]
+ , Graph sym var
+ , Pfun pvar var
+ ) | == var & == pvar
+
+build pattern node (heap,nodes,graph,mapping)
+| seen
+= (heap,[seenas:nodes],graph,mapping)
+| not closed
+= (heap`,[node`:nodes],graph,mapping`)
+= (heap``,[node`:nodes],graph``,mapping``)
+ where (seen,seenas) = apply mapping node
+ [node`:heap`] = heap
+ mapping` = extend node node` mapping
+ (closed,(f,params)) = varcontents pattern node
+ (heap``,params``,graph``,mapping``)
+ = foldr (build pattern) (heap`,[],graph`,mapping`) params
+ graph` = updategraph node` (f,params``) graph
+
+/*
+Mapping
+
+> getmap pattern patnode graph node
+> = getmapping nomatch pattern graph (patnode,node) id emptypfun
+> where nomatch = error "getmap: pattern and graph do not match"
+
+> existmap pattern patnode graph node
+> = getmapping False pattern graph (patnode,node) (const True) emptypfun
+*/
+
+getmapping
+ :: tsym
+ (Graph sym pvar)
+ (Graph sym var)
+ !(pvar,var)
+ ((Pfun pvar var) -> tsym)
+ !(Pfun pvar var)
+ -> tsym
+ | == sym
+ & == var
+ & == pvar
+
+getmapping failure patgraph graph (patnode,node) success mapping
+| seen
+= if (seenas==node) (success mapping) failure
+| not patdef
+= success mapping`
+| not (def && patfunc==func && eqlen patargs args)
+= failure
+= foldr (getmapping failure patgraph graph) success (zip2 patargs args) mapping`
+ where (seen,seenas) = apply mapping patnode
+ (patdef,(patfunc,patargs)) = varcontents patgraph patnode
+ (def,(func,args)) = varcontents graph node
+ mapping` = extend patnode node mapping
+
+/*
+The foldfn operation folds an area of a graph back to a function call.
+The following two conditions must be satisfied in order not to need a
+heap of fresh nodes:
+
+ 1: At least one node is freed by the fold operation to hold the root of
+ the redex. This is the root of the reduct; since it must be freed,
+ the rule that is folded by must not be a projection function;
+
+ 2: No other new nodes are necessary. Therefore, all nodes of the
+ pattern of the rule that is folded by except the root must also
+ occur in the replacement.
+
+Furthermore, the pattern of the rule is only given by its root symbol
+and its arguments; the arguments are open nodes.
+
+*/
+
+foldfn
+ :: (Pfun pvar var) // Matching of replacement
+ sym // Symbol at root of pattern
+ [pvar] // Arguments of pattern
+ pvar // Root of replacement
+ (Graph sym var) // Subject graph
+ -> Graph sym var // Folded subject
+ | == pvar
+
+foldfn matching symbol arguments replacementroot sgraph
+= updategraph (domatching replacementroot) (symbol,map domatching arguments) sgraph
+ where domatching = total nomatching matching
+ nomatching = abort "foldfn: no matching of argument of pattern"