aboutsummaryrefslogblamecommitdiff
path: root/sucl/rewr.icl
blob: 4b584ae72f45ba3b5c05f7142d35a7db2fdcd1c9 (plain) (tree)
1
2
3
4
                          
       
































































































                                                                                               
               






                                                          
                                               





































































































                                                                                   
implementation module rewr

// $Id$

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

rewrinstantiate
 :: .(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

rewrinstantiate 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"