aboutsummaryrefslogtreecommitdiff
path: root/sucl/graph.icl
diff options
context:
space:
mode:
Diffstat (limited to 'sucl/graph.icl')
-rw-r--r--sucl/graph.icl427
1 files changed, 0 insertions, 427 deletions
diff --git a/sucl/graph.icl b/sucl/graph.icl
deleted file mode 100644
index e0499e0..0000000
--- a/sucl/graph.icl
+++ /dev/null
@@ -1,427 +0,0 @@
-implementation module graph
-
-// $Id$
-
-import pfun
-import basic
-import general
-import StdEnv
-
-/*
-
-graph.lit - Unrooted graphs
-===========================
-
-Description
------------
-
-This script implements an abstract type for unrooted graphs and useful
-functions to manipulate them.
-
-*/
-
-// A mapping from variables to nodes (unrooted)
-:: Graph sym var
- = GraphAlias !(Pfun var (Node sym var))
-
-// A node, bearing the contents of a variable
-:: Node sym var
- :== (sym,[var])
-
-// ==> Symbols and variables are going to be defined in different modules.
-// They're here now because I don't want to throw them away.
-:: Symbol
- = Apply // Unwritten expression application
- | Cons // Non-empty list
- | Nil // Empty list
- | Int Int // A specified integer
- | Char Char // A specified character
- | User String String // A user-supplied symbol
- | Tuple Int // A tuple symbol of specified arity
- | Select Int Int // A tuple selection operator of specified arity and index
- | If // Predefined IF function
- | Bool Bool // A specified boolean
-// | MkRecord [Field] // Record construction?
-// | GetField [Field] Field // Record field selection?
-
-:: Variable
- = Named String // Variable was named in the program
- | Anonymous Int // Implicit variable
-
-/*
-
-> emptygraph = emptypfun
-> updategraph = extend
-> prunegraph = restrict
-> restrictgraph = domres
-> redirectgraph = postcomp.mapsnd.map
-> overwritegraph = overwrite
-> showgraph showfunc shownode = showpfun shownode (showpair showfunc (showlist shownode))
-*/
-
-// The empty set of bindings
-emptygraph :: .Graph sym var
-emptygraph = GraphAlias emptypfun
-
-updategraph :: var .(Node sym var) !.(Graph sym var) -> .Graph sym var
-updategraph var node graph = mapgraph (extend var node) graph
-
-prunegraph :: var !.(Graph sym var) -> .Graph sym var
-prunegraph var graph = mapgraph (restrict var) graph
-
-restrictgraph :: .[var] .(Graph sym var) -> .Graph sym var | == var
-restrictgraph vars graph = mapgraph (domres vars) graph
-
-redirectgraph :: (var->var) !.(Graph sym var) -> .Graph sym var
-redirectgraph redirection graph
-= mapgraph (postcomp (mapsnd (map redirection))) graph
-
-overwritegraph :: !.(Graph sym var) !.(Graph sym var) -> .Graph sym var
-overwritegraph (GraphAlias newpf) oldgraph = mapgraph (overwrite newpf) oldgraph
-
-movegraph :: (var1->var2) !.[var1] .(Graph sym var1) -> .Graph sym var2 | == var1
-movegraph movevar varspace oldgraph
-= foldr addvar emptygraph varspace
- where addvar var
- | def
- = updategraph (movevar var) (sym,map movevar args)
- = id
- where (def,(sym,args)) = varcontents oldgraph var
-
-varcontents :: !.(Graph sym var) var -> (.Bool,Node sym var) | == var
-varcontents (GraphAlias pfun) v
-= (total (False,(nosym,noargs)) o postcomp found) pfun v
- where found x = (True,x)
- nosym = abort "varcontents: getting symbol of free variable"
- noargs = abort "varcontents: getting arguments of free variable"
-
-graphvars :: .(Graph sym var) !.[var] -> (.[var],.[var]) | == var
-graphvars graph roots
-= graphvars` [] graph roots
-
-// Finds bound and free variables in a graph
-// Excludes the variables only reachable through "prune"
-graphvars` :: .[var] .(Graph sym var) .[var] -> (.[var],.[var]) | == var
-graphvars` prune graph roots
-= snd (foldlr ns (prune,([],[])) roots)
- where ns var seenboundfree
- | isMember var seen = seenboundfree
- | not def = ([var:seen],(bound,[var:free]))
- = (seen`,([var:bound`],free`))
- where (seen`,(bound`,free`)) = foldlr ns ([var:seen],boundfree) args
- (def,(_,args)) = varcontents graph var
- (seen,boundfree=:(bound,free)) = seenboundfree
-varlist :: .(Graph sym var) !.[var] -> .[var] | == var
-varlist graph roots
-= depthfirst arguments id roots
- where arguments var
- | def = args
- = []
- where (def,(_,args)) = varcontents graph var
-
-/*
-> prefix graph without nodes
-> = foldlr f (without,[]) nodes
-> where f node (seen,nodes)
-> = (seen,nodes), if member seen node
-> = (seen',node:nodes'), otherwise
-> where (seen',nodes')
-> = (node:seen,nodes), if ~def
-> = foldlr f (node:seen,nodes) args, otherwise
-> (def,(sym,args)) = nodecontents graph node
-*/
-prefix :: .(Graph sym var) .[var] !.[var] -> .([var],[var]) | == var
-prefix graph without vars
-= foldlr f (without,[]) vars
- where f var (seen,vars)
- | isMember var seen = (seen,vars)
- = (seen`,[var:vars`])
- where (seen`,vars`)
- = if (not def) ([var:seen],vars)
- (foldlr f ([var:seen],vars) args)
- (def,(_,args)) = varcontents graph var
-
-/*
-> printgraph showfunc shownode graph nodes
-> = prntgrph showfunc shownode (refcount graph nodes) graph nodes
-
-> prntgrph showfunc shownode count graph
-> = snd.foldlr pg ([],[])
-> where pg node (seen,reprs)
-> = (seen2,repr3:reprs)
-> where repr3
-> = shownode node++':':repr2, if ~member seen node & def & count node>1
-> = repr2, otherwise
-> (seen2,repr2)
-> = (seen,shownode node), if member seen node \/ ~def
-> = (seen1,showfunc func), if args=[]
-> = (seen1,'(':showfunc func++concat (map (' ':) repr1)++")"), otherwise
-> (seen1,repr1) = foldlr pg (node:seen,[]) args
-> (def,(func,args)) = nodecontents graph node
-*/
-
-printgraph :: .(Graph sym var) .[var] -> .[String] | toString sym & toString var & == var
-printgraph graph nodes = printgraphBy toString toString graph nodes
-
-printgraphBy :: (sym->String) (var->String) .(Graph sym var) .[var] -> .[String] | == var
-printgraphBy showsym showvar graph nodes
-= prntgrph showsym showvar (refcount graph nodes) graph nodes
-
-prntgrph showsym showvar count graph nodes
-= snd (foldlr pg ([],[]) nodes)
- where pg node (seen,reprs)
- = (seen2,[repr3:reprs])
- where repr3
- = if (not (isMember node seen) && def && count node>1)
- (showvar node+++":"+++repr2)
- repr2
- (seen2,repr2)
- = if (isMember node seen || not def)
- (seen,showvar node)
- (if (args==[])
- (seen1,showsym func)
- (seen1,"("+++showsym func+++foldr (+++) ")" (map ((+++)" ") repr1)))
- (seen1,repr1) = foldlr pg ([node:seen],[]) args
- (def,(func,args)) = varcontents graph node
-
-/*
-> refcount graph
-> = foldr rfcnt (const 0)
-> where rfcnt node count
-> = count', if count node>0 \/ ~def
-> = foldr rfcnt count' args, otherwise
-> where count' = inc node count
-> (def,(func,args)) = nodecontents graph node
-
-> inc n f n = f n+1
-> inc m f n = f n
-*/
-refcount :: .(Graph sym var) !.[var] -> (var -> Int) | == var
-refcount graph roots
-= foldr rfcnt (const 0) roots
- where rfcnt var count
- | (count var>0) || (not def) = count`
- = foldr rfcnt count` args
- where count` = inccounter var count
- (def,(_,args)) = varcontents graph var
-
-/*
-
-Compilegraph compiles a graph from parts.
-Uses in Miranda:
- * reading a parsed program from a file.
-*/
-
-compilegraph :: ![(var,Node sym var)] -> Graph sym var
-compilegraph nds = foldr (uncurry updategraph) emptygraph nds
-
-/*
-
-`Instance g1 g2' determines whether g2 is an instance of g1.
-Uses in Miranda:
- * strat.lit.m: checking whether the strategy is starting a graph that is already in the history.
- * newfold.lit.m: checking whether a tail of the spine occurs in the history.
-
-> instance :: (graph * ***,***) -> (graph * **,**) -> bool
-> instance (pgraph,pnode) (sgraph,snode)
-> = errs=[]
-> where (seen,mapping,errs) = instantiate (pgraph,sgraph) (pnode,snode) ([],[],[])
-
-*/
-
-isinstance
- :: (.Graph sym pvar,pvar)
- (.Graph sym var,var)
- -> Bool
- | == sym
- & == var
- & == pvar
-
-isinstance (pgraph,pvar) (sgraph,svar)
-= isEmpty (thd3 (findmatching (pgraph,sgraph) (pvar,svar) ([],[],[]))) <--- "graph.isinstance ends"
-
-/*
-
-Suppose `Instantiate (pattern,graph) (pnode,gnode) (seen,mapping,errs)'
-returns `(seen',mapping',errs')'.
-
-Then `mapping'' is the best attempt at extending the `mapping' to show that `graph' is an instance of `pattern'.
-If it is not, then `errs'' is `errs' extended with node pairs that fail to match.
-In the mean time, the nodes pairs examined are added to `seen', and returned as `seen''.
-Node pairs already in `seen' are assumed to have already been checked and are not checked again.
-
-Uses in Miranda:
- * extract.lit.m: used to find instances of patterns in the termination history, while folding trace tips.
- * transform.lit.m: Uses a different `instantiate' from rewr.lit.m.
-
-`Instantiateargs' is the logical extension of `instantiate' to lists of node pairs.
-
-*/
-
-instantiate ::
- (Graph sym pvar,Graph sym var)
- (pvar,var)
- ([(pvar,var)],[(pvar,var)],[(pvar,var)])
- -> ([(pvar,var)],[(pvar,var)],[(pvar,var)])
- | == sym
- & == var
- & == pvar
-
-instantiate (pgraph,sgraph) (pnode,snode) (seen,mapping,errs)
-| isMember psnode seen
- = (seen,mapping,errs)
-| isMember pnode (map fst seen)
- = ([psnode:seen],mapping,[psnode:errs])
-| not pdef
- = ([psnode:seen],[psnode:mapping],errs)
-| not sdef
- = ([psnode:seen],mapping,[psnode:errs])
-| not (psym==ssym && eqlen pargs sargs)
- = ([psnode:seen],mapping,[psnode:errs])
-= (seen`,[psnode:mapping`],errs`)
- where (pdef,(psym,pargs)) = varcontents pgraph pnode
- (sdef,(ssym,sargs)) = varcontents sgraph snode
- (seen`,mapping`,errs`) = instantiateargs (pgraph,sgraph) (zip2 pargs sargs) ([psnode:seen],mapping,errs)
- psnode = (pnode,snode)
-
-instantiateargs ::
- (Graph sym pvar,Graph sym var)
- [(pvar,var)]
- ([(pvar,var)],[(pvar,var)],[(pvar,var)])
- -> ([(pvar,var)],[(pvar,var)],[(pvar,var)])
- | == sym
- & == var
- & == pvar
-
-instantiateargs psgraph [] sme = sme
-instantiateargs psgraph [psnode:psnodes] (seen,mapping,errs)
-= (seen``,mapping``,errs``)
- where (seen`,mapping``,errs``) = instantiate psgraph psnode (seen,mapping`,errs`)
- (seen``,mapping`,errs`) = instantiateargs psgraph psnodes (seen`,mapping,errs)
-
-:: Matchstate var pvar
- :== ( [(pvar,var)] // Pattern-subject var combo's already visited
- , [(pvar,var)] // Mapping from pattern vars to subject vars
- , [(pvar,var)] // Pattern-subject var combo's that don't match (different symbol or arities)
- )
-
-findmatching
- :: (Graph sym pvar,Graph sym var)
- .(pvar,var)
- u:(Matchstate var pvar)
- -> u:Matchstate var pvar
- | == sym
- & == var
- & == pvar
-
-findmatching (pgraph,sgraph) (pvar,svar) (seen,mapping,errs)
-| isMember psvar seen
-= (seen,mapping,errs)
-| isMember pvar (map fst seen)
-= ([psvar:seen],mapping,[psvar:errs])
-| not pdef
-= ([psvar:seen],[psvar:mapping],errs)
-| not sdef
-= ([psvar:seen],mapping,[psvar:errs])
-| not (psym==ssym && eqlen pargs sargs)
-= ([psvar:seen],mapping,[psvar:errs])
-= (seen`,[psvar:mapping`],errs`)
- where (pdef,(psym,pargs)) = varcontents pgraph pvar
- (sdef,(ssym,sargs)) = varcontents sgraph svar
- (seen`,mapping`,errs`) = findargmatching (pgraph,sgraph) (zip2 pargs sargs) ([psvar:seen],mapping,errs)
- psvar = (pvar,svar)
-
-findargmatching
- :: (Graph sym pvar,Graph sym var)
- [.(pvar,var)]
- u:(Matchstate var pvar)
- -> v:Matchstate var pvar
- | == sym
- & == var
- & == pvar
- , [u<=v]
-
-findargmatching psgraph [] seenmappingerrs = seenmappingerrs
-findargmatching psgraph [psvar:psvars] (seen,mapping,errs)
-= (seen``,mapping``,errs``)
- where (seen`,mapping``,errs``) = findmatching psgraph psvar (seen,mapping`,errs`)
- (seen``,mapping`,errs`) = findargmatching psgraph psvars (seen`,mapping,errs)
-
-/*
-
-------------------------------------------------------------------------
-
-A folding function for graphs.
-Uses in Miranda:
- * clean.lit.m: pretty-printing rewrite rules.
- * pretty.lit.m: pretty-printing rewrite rules.
-
-> foldgraph
-> :: (**->***->***) ->
-> (**->***) ->
-> (*->[***]->***) ->
-> graph * ** ->
-> [**] ->
-> [***]
-
-> foldgraph folddef foldref foldcont graph roots
-> = foldedroots
-> where count = refcount graph roots
-> (unused,foldedroots) = foldlm fold ([],roots)
-> fold (seen,node)
-> = (seen,foldref node), if member seen node
-> = (seen'',cond (def&count node>1) (folddef node folded) folded), otherwise
-> where (seen'',folded)
-> = (seen',foldcont sym foldedargs), if def
-> = (node:seen,foldref node), otherwise
-> (seen',foldedargs) = foldlm fold (node:seen,args)
-> (def,(sym,args)) = nodecontents graph node
-
-`Paths' lists all paths in a graph.
-Never used in Miranda.
-
-> paths :: graph * ** -> ** -> [[**]]
-> paths graph node
-> = paths' [] node []
-> where paths' top node rest
-> = rest, if member top node
-> = top':cond def (foldr (paths' top') rest args) rest, otherwise
-> where (def,(sym,args)) = nodecontents graph node
-> top' = node:top
-
-`Extgraph sgraph pattern pnodes matching' extends some graph according
-to the closed nodes in sgraph that closed nodes in pgraph are mapped to.
-That is, we take the nodes from `pnodes', see if they are closed,
-follow the mapping to `sgraph', see if they are closed there too,
-and if so, add the contents in `sgraph' to the graph we're extending.
-
-Uses in Miranda:
- * newfold.lit.m: function `findspinepart', to find parts of a spine.
- Specifically, to extend history patterns as one traverses down the trace.
- * transtree.lit.m: to extend the history when the reduce transformation is applied.
- * transform.lit.m: idem.
-
-`Extgraph' is excluded in most import statements,
-but there doesn't seem to be any other definition of it.
-*/
-
-extgraph :: (Graph sym var) (Graph sym pvar) [pvar] (Pfun pvar var) (Graph sym var) -> Graph sym var | == var & == pvar
-extgraph sgraph pattern pnodes matching graph
-= foldr addnode graph pnodes
- where addnode pnode
- = if (fst (varcontents pattern pnode)) (total id (postcomp addnode` matching) pnode) id
- addnode` snode
- = if sdef (updategraph snode scont) id
- where (sdef,scont) = varcontents sgraph snode
-
-mapgraph ::
- !( (Pfun var1 (sym1,[var1]))
- -> Pfun var2 (sym2,[var2])
- )
- !.(Graph sym1 var1)
- -> .Graph sym2 var2
-mapgraph f (GraphAlias pfun) = GraphAlias (f pfun)
-
-instance == (Graph sym var) | == sym & == var
-where (==) (GraphAlias pf1) (GraphAlias pf2)
- = pf1 == pf2