aboutsummaryrefslogtreecommitdiff
path: root/sucl/spine.icl
diff options
context:
space:
mode:
Diffstat (limited to 'sucl/spine.icl')
-rw-r--r--sucl/spine.icl314
1 files changed, 300 insertions, 14 deletions
diff --git a/sucl/spine.icl b/sucl/spine.icl
index 930ffc7..89da146 100644
--- a/sucl/spine.icl
+++ b/sucl/spine.icl
@@ -2,9 +2,12 @@ implementation module spine
// $Id$
+import history
import rule
+import graph
import pfun
import basic
+from general import No,Yes
import StdEnv
/*
@@ -164,7 +167,7 @@ in a graph.
| MissingCase // All alternatives failed for a function symbol
| Open (Rgraph sym pvar) // Need root normal form of open node for matching
| Partial (Rule sym pvar) (Pfun pvar var) pvar (Spine sym var pvar) // A rule was strictly partially matched
- | Unsafe (Rgraph sym var) // Terminated due to immininent recursion
+ | Unsafe (HistoryPattern sym var) // Terminated due to immininent recursion
| Redex (Rule sym pvar) (Pfun pvar var) // Total match
| Strict // Need root normal form due to strictness
@@ -200,18 +203,18 @@ in a graph.
*/
foldspine
- :: !(var .subresult -> .result)
- .subresult
- .subresult
- (Int .result -> .subresult)
- .subresult
- ((Rgraph sym pvar) -> .subresult)
- ((Rule sym pvar) (Pfun pvar var) pvar .result -> .subresult)
- ((Rgraph sym var) -> .subresult)
- ((Rule sym pvar) (Pfun pvar var) -> .subresult)
- .subresult
- .(Spine sym var pvar)
- -> .result
+ :: !(var .subresult -> .result) // Fold the spine itself
+ .subresult // Fold a Cycle subspine
+ .subresult // Fold a Delta subspine
+ (Int .result -> .subresult) // Fold a Force subspine
+ .subresult // Fold a MissingCase subspine
+ ((Rgraph sym pvar) -> .subresult) // Fold an Open subspine
+ ((Rule sym pvar) (Pfun pvar var) pvar .result -> .subresult) // Fold a Partial subspine
+ ((HistoryPattern sym var) -> .subresult) // Fold an Unsafe subspine
+ ((Rule sym pvar) (Pfun pvar var) -> .subresult) // Fold a Redex subspine
+ .subresult // Fold a Strict subspine
+ .(Spine sym var pvar) // The spine to fold
+ -> .result // The final result
foldspine pair cycle delta force missingcase open partial unsafe redex strict spine
= fold spine
@@ -224,7 +227,7 @@ foldspine pair cycle delta force missingcase open partial unsafe redex strict sp
foldsub MissingCase = missingcase
foldsub (Open rgraph) = open rgraph
foldsub (Partial rule matching rnode spine) = partial rule matching rnode (fold spine)
- foldsub (Unsafe rgraph) = unsafe rgraph
+ foldsub (Unsafe histpat) = unsafe histpat
foldsub (Redex rule matching) = redex rule matching
foldsub Strict = strict
@@ -244,3 +247,286 @@ ifopen open other spine
= foldoptional other (checkopen o spinetip) spine
where checkopen (onode,Open pattern) = open
checkopen tip = other
+
+
+/*********************************************
+* Extending the history according to a spine *
+*********************************************/
+
+// A function that associates specific patterns with extensible nodes
+// To be used for extending history patterns
+:: LinkExtender sym var
+ :== (Link var) // The extensible link to look for
+ -> HistoryPattern sym var // The associated pattern
+
+extendhistory
+ :: (Graph sym var) // Subject graph
+ (Spine sym var pvar) // Spine leading to the reduction operation
+ (History sym var) // Old history
+ -> History sym var // New history
+ | == sym
+ & == var
+ & == pvar
+
+extendhistory sgraph spine history
+ = [newpattern:touchmod history]
+ where (newpattern,_,extender)
+ = foldspine extendpair extenddefault extenddefault (extendforce sgraph) extenddefault extendopen (extendpartial sgraph) (const extenddefault) (extendredex sgraph) extenddefault spine No Extensible
+ touchmod = map (mapsnd (patextend extender))
+
+patextend
+ :: (LinkExtender sym var)
+ (HistoryPattern sym var)
+ -> HistoryPattern sym var
+
+patextend extender (Closed sym args) = Closed sym (map (patextend extender) args)
+patextend extender OpenHist = OpenHist
+patextend extender (Extensible link) = extender link
+
+extendpair
+ :: var // Subject node-id where spine is rooted
+ ( var
+ (Link var)
+ (LinkExtender sym var)
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var
+ , LinkExtender sym var
+ )
+ )
+ (Link var) // Link in subject graph to this spine
+ (LinkExtender sym var) // Input link extender
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var // Returned history pattern
+ , LinkExtender sym var // Returned link extender
+ )
+
+extendpair snode extendsub link extender
+ = extendsub snode link extender
+
+extenddefault
+ :: var
+ (Link var)
+ (LinkExtender sym var)
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var
+ , LinkExtender sym var
+ )
+extenddefault _ link extender
+ = (nonewpattern,Extensible link,extender)
+ where nonewpattern = abort "history: extenddefault: no new pattern for default spine"
+
+// Extend history for a Force spine
+// FIXME: For now, only look at function node and to-be-strict argument
+// Forget what was already determined strict
+extendforce
+ :: (Graph sym var)
+ Int
+ ( (Link var)
+ (LinkExtender sym var)
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var
+ , LinkExtender sym var
+ )
+ )
+ var
+ (Link var)
+ (LinkExtender sym var)
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var
+ , LinkExtender sym var
+ )
+ | == var
+
+extendforce sgraph argno forcesub snode link extender0
+ | not sdef
+ = abort "history: extendforce: force from open node-id???"
+ = (newpattern,histpat1,extender2)
+ where (newpattern,histpat0,extender1) = forcesub (Yes (snode,argno)) extender0
+ histpat1 = Closed ssym [argpat i \\ i <- [0..] & _ <- sargs]
+ argpat i
+ = if (i==argno) histpat0 (Extensible (Yes (snode,i)))
+ (sdef,(ssym,sargs)) = varcontents sgraph snode
+ extender2 = adjust link histpat1 extender1
+
+// Extend history patterns according to an Open spine
+extendopen
+ :: rgraph // Pattern to drive instantiation (not used)
+ var // Node-id in subject graph that was open
+ (Link var) // Where subject graph pointed to this open node-id
+ (LinkExtender sym var) // Input link extender
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var // Pattern for this spine
+ , LinkExtender sym var // Resulting link extender
+ )
+ | == var
+
+extendopen _ snode link extender0
+ = (newpattern,histpat,extender1)
+ where histpat = OpenHist
+ newpattern = (snode,histpat)
+ extender1 = adjust link histpat extender0
+
+extendpartial
+ :: (Graph sym var) // Subject graph
+ (Rule sym pvar) // Applied rewrite rule
+ (Pfun pvar var) // Partial match from rewrite rule's pattern to subject graph
+ pvar // Node-id in rule where partial match went to subspine
+ ( (Link var) // Link passed to subspine handler
+ (LinkExtender sym var) // Link extender input to subspine handler
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var // Pattern returned for subspine
+ , LinkExtender sym var // Link extender returned for subspine
+ )
+ )
+ var // Node-id in subject with function application
+ (Link var) // Link to root of partial match in subject graph
+ (LinkExtender sym var) // Remaining link extender
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var // History patterns with derived pattern prefixed
+ , LinkExtender sym var // Extended link extender
+ )
+ | == sym
+ & == var
+ & == pvar
+
+extendpartial sgraph rule matching subnode extendsub snode link restextender
+ = extendfunction sgraph rule matching ((==)subnode) (const extendsub) snode link restextender
+
+extendredex
+ :: (Graph sym var) // Subject graph
+ (Rule sym pvar) // Applied rewrite rule
+ (Pfun pvar var) // Partial match from rewrite rule's pattern to subject graph
+ var // Root of redex in subject graph
+ (Link var) // Link to root of redex in subject graph
+ (LinkExtender sym var) // Remaining link extender
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var // History patterns with derived pattern prefixed
+ , LinkExtender sym var // Extended link extender
+ )
+ | == sym
+ & == var
+ & == pvar
+
+extendredex sgraph rule matching snode link extender
+ = extendfunction sgraph rule matching (const False) nosub snode link extender
+ where nosub = abort "history: extendredex: full match with subspine??"
+
+extendfunction
+ :: (Graph sym var) // Subject graph
+ (Rule sym pvar) // Applied rewrite rule
+ (Pfun pvar var) // Partial match from rewrite rule's pattern to subject graph
+ (pvar -> Bool) // Checks whether the subspine applies here
+ ( (HistoryAssociation sym var)
+ (Link var) // Link passed to subspine handler
+ (LinkExtender sym var) // Link extender input to subspine handler
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var // Pattern returned for subspine
+ , LinkExtender sym var // Link extender returned for subspine
+ )
+ )
+ var // Root of partial match in subject graph
+ (Link var) // Link to root of partial match in subject graph
+ (LinkExtender sym var) // Remaining link extender
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var // History patterns with derived pattern prefixed
+ , LinkExtender sym var // Extended link extender
+ )
+ | == sym
+ & == var
+ & == pvar
+
+extendfunction sgraph rule matching issub extendsub snode link extender0
+ | not sdef
+ = abort "history: extendfunction: partial or full match at open node-id???"
+ = (newpattern,thispat,extender2)
+ where extender2 = adjust link thispat extender1
+ thispat = Closed ssym argpatts
+ (newpattern,argpatts,extender1) = extendnodes sgraph rgraph matching snode issub extendsub thisnewpattern extender0 rargs
+ (sdef,(ssym,_)) = varcontents sgraph snode
+ rgraph = rulegraph rule
+ rargs = arguments rule
+ thisnewpattern = (snode,thispat)
+
+extendnodes
+ :: (Graph sym var) // Subject graph
+ (Graph sym pvar) // Applied rewrite rule
+ (Pfun pvar var) // Partial match from rewrite rule's pattern to subject graph
+ var // Parent node-id in subject graph to this node-id list for creating links
+ (pvar -> Bool) // Tells if this is where the subspine was attached
+ ( (HistoryAssociation sym var)
+ (Link var) // Link passed to subspine handler
+ (LinkExtender sym var) // Link extender input to subspine handler
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var // Pattern returned for subspine
+ , LinkExtender sym var // Link extender returned for subspine
+ )
+ )
+ (HistoryAssociation sym var)
+ (LinkExtender sym var) // Remaining link extender
+ [pvar] // Node-ids in rule to handle
+ -> ( HistoryAssociation sym var
+ , [HistoryPattern sym var] // History patterns with derived pattern prefixed
+ , LinkExtender sym var // Extended link extender
+ )
+ | == sym
+ & == var
+ & == pvar
+
+extendnodes sgraph rgraph matching sparent issub extendsub newpattern restextender rnodes
+ = foldr (extendnode sgraph rgraph matching issub extendsub) (newpattern,[],restextender) (zip2 links rnodes)
+ where links = [Yes (sparent,i)\\i<-[0..]]
+
+extendnode
+ :: (Graph sym var) // Subject graph
+ (Graph sym pvar) // Applied rewrite rule
+ (Pfun pvar var) // Partial match from rewrite rule's pattern to subject graph
+ (pvar -> Bool) // Tells if this is where the subspine was attached
+ ( (HistoryAssociation sym var)
+ (Link var) // Link passed to subspine handler
+ (LinkExtender sym var) // Link extender input to subspine handler
+ -> ( HistoryAssociation sym var
+ , HistoryPattern sym var // Pattern returned for subspine
+ , LinkExtender sym var // Link extender returned for subspine
+ )
+ )
+ ( Link var // Referring link to current node-id
+ , pvar // Current node-id in rule
+ )
+ ( HistoryAssociation sym var
+ , [HistoryPattern sym var] // History patterns to prefix derived patterns to
+ , (LinkExtender sym var) // Remaining link extender
+ )
+ -> ( HistoryAssociation sym var
+ , [HistoryPattern sym var] // History patterns with derived pattern prefixed
+ , (LinkExtender sym var) // Extended link extender
+ )
+ | == sym
+ & == var
+ & == pvar
+
+extendnode sgraph rgraph matching issub extendsub (link,rnode) (newpattern0,rest,extender0)
+ | issub rnode
+ = (subnewpattern,[subpattern:rest],subextender)
+ | rdef
+ = foldpfun mapped unmapped matching rnode
+ = unmapped
+ where (subnewpattern,subpattern,subextender)
+ = extendsub newpattern0 link extender0
+ mapped snode
+ = (newpattern1,[thispat:rest],extender2)
+ where extender2 = adjust link thispat extender1
+ thispat = Closed rsym argpatts
+ (newpattern1,argpatts,extender1) = extendnodes sgraph rgraph matching snode issub extendsub newpattern0 extender0 rargs
+ unmapped
+ = (newpattern0,[Extensible link:rest],extender0)
+ (rdef,(rsym,rargs)) = varcontents rgraph rnode
+
+
+/****************
+* Miscellaneous *
+****************/
+
+instance == (Optional a) | == a
+ where (==) No No = True
+ (==) (Yes x1) (Yes x2) = x1==x2
+ (==) _ _ = False