src/Tools/Metis/src/TermNet.sml
changeset 39353 7f11d833d65b
parent 23510 4521fead5609
parent 39349 2d0a4361c3ef
child 39443 e330437cd22a
equal deleted inserted replaced
39313:41ce0b56d858 39353:7f11d833d65b
     1 (* ========================================================================= *)
     1 (* ========================================================================= *)
     2 (* MATCHING AND UNIFICATION FOR SETS OF FIRST ORDER LOGIC TERMS              *)
     2 (* MATCHING AND UNIFICATION FOR SETS OF FIRST ORDER LOGIC TERMS              *)
     3 (* Copyright (c) 2001-2006 Joe Hurd, distributed under the BSD License *)
     3 (* Copyright (c) 2001-2006 Joe Hurd, distributed under the BSD License       *)
     4 (* ========================================================================= *)
     4 (* ========================================================================= *)
     5 
     5 
     6 structure TermNet :> TermNet =
     6 structure TermNet :> TermNet =
     7 struct
     7 struct
     8 
     8 
     9 open Useful;
     9 open Useful;
    10 
    10 
    11 (* ------------------------------------------------------------------------- *)
    11 (* ------------------------------------------------------------------------- *)
    12 (* Quotient terms                                                            *)
    12 (* Anonymous variables.                                                      *)
    13 (* ------------------------------------------------------------------------- *)
    13 (* ------------------------------------------------------------------------- *)
    14 
    14 
    15 datatype qterm = VAR | FN of NameArity.nameArity * qterm list;
    15 val anonymousName = Name.fromString "_";
    16 
    16 val anonymousVar = Term.Var anonymousName;
    17 fun termToQterm (Term.Var _) = VAR
    17 
    18   | termToQterm (Term.Fn (f,l)) = FN ((f, length l), map termToQterm l);
    18 (* ------------------------------------------------------------------------- *)
       
    19 (* Quotient terms.                                                           *)
       
    20 (* ------------------------------------------------------------------------- *)
       
    21 
       
    22 datatype qterm =
       
    23     Var
       
    24   | Fn of NameArity.nameArity * qterm list;
       
    25 
       
    26 local
       
    27   fun cmp [] = EQUAL
       
    28     | cmp (q1_q2 :: qs) =
       
    29       if Portable.pointerEqual q1_q2 then cmp qs
       
    30       else
       
    31         case q1_q2 of
       
    32           (Var,Var) => EQUAL
       
    33         | (Var, Fn _) => LESS
       
    34         | (Fn _, Var) => GREATER
       
    35         | (Fn f1, Fn f2) => fnCmp f1 f2 qs
       
    36 
       
    37   and fnCmp (n1,q1) (n2,q2) qs =
       
    38     case NameArity.compare (n1,n2) of
       
    39       LESS => LESS
       
    40     | EQUAL => cmp (zip q1 q2 @ qs)
       
    41     | GREATER => GREATER;
       
    42 in
       
    43   fun compareQterm q1_q2 = cmp [q1_q2];
       
    44 
       
    45   fun compareFnQterm (f1,f2) = fnCmp f1 f2 [];
       
    46 end;
       
    47 
       
    48 fun equalQterm q1 q2 = compareQterm (q1,q2) = EQUAL;
       
    49 
       
    50 fun equalFnQterm f1 f2 = compareFnQterm (f1,f2) = EQUAL;
       
    51 
       
    52 fun termToQterm (Term.Var _) = Var
       
    53   | termToQterm (Term.Fn (f,l)) = Fn ((f, length l), map termToQterm l);
    19 
    54 
    20 local
    55 local
    21   fun qm [] = true
    56   fun qm [] = true
    22     | qm ((VAR,_) :: rest) = qm rest
    57     | qm ((Var,_) :: rest) = qm rest
    23     | qm ((FN _, VAR) :: _) = false
    58     | qm ((Fn _, Var) :: _) = false
    24     | qm ((FN (f,a), FN (g,b)) :: rest) = f = g andalso qm (zip a b @ rest);
    59     | qm ((Fn (f,a), Fn (g,b)) :: rest) =
       
    60       NameArity.equal f g andalso qm (zip a b @ rest);
    25 in
    61 in
    26   fun matchQtermQterm qtm qtm' = qm [(qtm,qtm')];
    62   fun matchQtermQterm qtm qtm' = qm [(qtm,qtm')];
    27 end;
    63 end;
    28 
    64 
    29 local
    65 local
    30   fun qm [] = true
    66   fun qm [] = true
    31     | qm ((VAR,_) :: rest) = qm rest
    67     | qm ((Var,_) :: rest) = qm rest
    32     | qm ((FN _, Term.Var _) :: _) = false
    68     | qm ((Fn _, Term.Var _) :: _) = false
    33     | qm ((FN ((f,n),a), Term.Fn (g,b)) :: rest) =
    69     | qm ((Fn ((f,n),a), Term.Fn (g,b)) :: rest) =
    34       f = g andalso n = length b andalso qm (zip a b @ rest);
    70       Name.equal f g andalso n = length b andalso qm (zip a b @ rest);
    35 in
    71 in
    36   fun matchQtermTerm qtm tm = qm [(qtm,tm)];
    72   fun matchQtermTerm qtm tm = qm [(qtm,tm)];
    37 end;
    73 end;
    38 
    74 
    39 local
    75 local
    40   fun qn qsub [] = SOME qsub
    76   fun qn qsub [] = SOME qsub
    41     | qn qsub ((Term.Var v, qtm) :: rest) =
    77     | qn qsub ((Term.Var v, qtm) :: rest) =
    42       (case NameMap.peek qsub v of
    78       (case NameMap.peek qsub v of
    43          NONE => qn (NameMap.insert qsub (v,qtm)) rest
    79          NONE => qn (NameMap.insert qsub (v,qtm)) rest
    44        | SOME qtm' => if qtm = qtm' then qn qsub rest else NONE)
    80        | SOME qtm' => if equalQterm qtm qtm' then qn qsub rest else NONE)
    45     | qn _ ((Term.Fn _, VAR) :: _) = NONE
    81     | qn _ ((Term.Fn _, Var) :: _) = NONE
    46     | qn qsub ((Term.Fn (f,a), FN ((g,n),b)) :: rest) =
    82     | qn qsub ((Term.Fn (f,a), Fn ((g,n),b)) :: rest) =
    47       if f = g andalso length a = n then qn qsub (zip a b @ rest) else NONE;
    83       if Name.equal f g andalso length a = n then qn qsub (zip a b @ rest)
       
    84       else NONE;
    48 in
    85 in
    49   fun matchTermQterm qsub tm qtm = qn qsub [(tm,qtm)];
    86   fun matchTermQterm qsub tm qtm = qn qsub [(tm,qtm)];
    50 end;
    87 end;
    51 
    88 
    52 local
    89 local
    53   fun qv VAR x = x
    90   fun qv Var x = x
    54     | qv x VAR = x
    91     | qv x Var = x
    55     | qv (FN (f,a)) (FN (g,b)) =
    92     | qv (Fn (f,a)) (Fn (g,b)) =
    56       let
    93       let
    57         val _ = f = g orelse raise Error "TermNet.qv"
    94         val _ = NameArity.equal f g orelse raise Error "TermNet.qv"
    58       in
    95       in
    59         FN (f, zipwith qv a b)
    96         Fn (f, zipWith qv a b)
    60       end;
    97       end;
    61 
    98 
    62   fun qu qsub [] = qsub
    99   fun qu qsub [] = qsub
    63     | qu qsub ((VAR, _) :: rest) = qu qsub rest
   100     | qu qsub ((Var, _) :: rest) = qu qsub rest
    64     | qu qsub ((qtm, Term.Var v) :: rest) =
   101     | qu qsub ((qtm, Term.Var v) :: rest) =
    65       let
   102       let
    66         val qtm =
   103         val qtm =
    67             case NameMap.peek qsub v of NONE => qtm | SOME qtm' => qv qtm qtm'
   104             case NameMap.peek qsub v of NONE => qtm | SOME qtm' => qv qtm qtm'
    68       in
   105       in
    69         qu (NameMap.insert qsub (v,qtm)) rest
   106         qu (NameMap.insert qsub (v,qtm)) rest
    70       end
   107       end
    71     | qu qsub ((FN ((f,n),a), Term.Fn (g,b)) :: rest) =
   108     | qu qsub ((Fn ((f,n),a), Term.Fn (g,b)) :: rest) =
    72       if f = g andalso n = length b then qu qsub (zip a b @ rest)
   109       if Name.equal f g andalso n = length b then qu qsub (zip a b @ rest)
    73       else raise Error "TermNet.qu";
   110       else raise Error "TermNet.qu";
    74 in
   111 in
    75   fun unifyQtermQterm qtm qtm' = total (qv qtm) qtm';
   112   fun unifyQtermQterm qtm qtm' = total (qv qtm) qtm';
    76 
   113 
    77   fun unifyQtermTerm qsub qtm tm = total (qu qsub) [(qtm,tm)];
   114   fun unifyQtermTerm qsub qtm tm = total (qu qsub) [(qtm,tm)];
    78 end;
   115 end;
    79 
   116 
    80 local
   117 local
    81   fun qtermToTerm VAR = Term.Var ""
   118   fun qtermToTerm Var = anonymousVar
    82     | qtermToTerm (FN ((f,_),l)) = Term.Fn (f, map qtermToTerm l);
   119     | qtermToTerm (Fn ((f,_),l)) = Term.Fn (f, map qtermToTerm l);
    83 in
   120 in
    84   val ppQterm = Parser.ppMap qtermToTerm Term.pp;
   121   val ppQterm = Print.ppMap qtermToTerm Term.pp;
    85 end;
   122 end;
    86 
   123 
    87 (* ------------------------------------------------------------------------- *)
   124 (* ------------------------------------------------------------------------- *)
    88 (* A type of term sets that can be efficiently matched and unified.          *)
   125 (* A type of term sets that can be efficiently matched and unified.          *)
    89 (* ------------------------------------------------------------------------- *)
   126 (* ------------------------------------------------------------------------- *)
    90 
   127 
    91 type parameters = {fifo : bool};
   128 type parameters = {fifo : bool};
    92 
   129 
    93 datatype 'a net =
   130 datatype 'a net =
    94     RESULT of 'a list
   131     Result of 'a list
    95   | SINGLE of qterm * 'a net
   132   | Single of qterm * 'a net
    96   | MULTIPLE of 'a net option * 'a net NameArityMap.map;
   133   | Multiple of 'a net option * 'a net NameArityMap.map;
    97 
   134 
    98 datatype 'a termNet = NET of parameters * int * (int * (int * 'a) net) option;
   135 datatype 'a termNet = Net of parameters * int * (int * (int * 'a) net) option;
    99 
   136 
   100 (* ------------------------------------------------------------------------- *)
   137 (* ------------------------------------------------------------------------- *)
   101 (* Basic operations.                                                         *)
   138 (* Basic operations.                                                         *)
   102 (* ------------------------------------------------------------------------- *)
   139 (* ------------------------------------------------------------------------- *)
   103 
   140 
   104 fun new parm = NET (parm,0,NONE);
   141 fun new parm = Net (parm,0,NONE);
   105 
   142 
   106 local
   143 local
   107   fun computeSize (RESULT l) = length l
   144   fun computeSize (Result l) = length l
   108     | computeSize (SINGLE (_,n)) = computeSize n
   145     | computeSize (Single (_,n)) = computeSize n
   109     | computeSize (MULTIPLE (vs,fs)) =
   146     | computeSize (Multiple (vs,fs)) =
   110       NameArityMap.foldl
   147       NameArityMap.foldl
   111         (fn (_,n,acc) => acc + computeSize n)
   148         (fn (_,n,acc) => acc + computeSize n)
   112         (case vs of SOME n => computeSize n | NONE => 0)
   149         (case vs of SOME n => computeSize n | NONE => 0)
   113         fs;
   150         fs;
   114 in
   151 in
   115   fun netSize NONE = NONE
   152   fun netSize NONE = NONE
   116     | netSize (SOME n) = SOME (computeSize n, n);
   153     | netSize (SOME n) = SOME (computeSize n, n);
   117 end;
   154 end;
   118 
   155 
   119 fun size (NET (_,_,NONE)) = 0
   156 fun size (Net (_,_,NONE)) = 0
   120   | size (NET (_, _, SOME (i,_))) = i;
   157   | size (Net (_, _, SOME (i,_))) = i;
   121 
   158 
   122 fun null net = size net = 0;
   159 fun null net = size net = 0;
   123 
   160 
   124 fun singles qtms a = foldr SINGLE a qtms;
   161 fun singles qtms a = foldr Single a qtms;
   125 
   162 
   126 local
   163 local
   127   fun pre NONE = (0,NONE)
   164   fun pre NONE = (0,NONE)
   128     | pre (SOME (i,n)) = (i, SOME n);
   165     | pre (SOME (i,n)) = (i, SOME n);
   129 
   166 
   130   fun add (RESULT l) [] (RESULT l') = RESULT (l @ l')
   167   fun add (Result l) [] (Result l') = Result (l @ l')
   131     | add a (input1 as qtm :: qtms) (SINGLE (qtm',n)) =
   168     | add a (input1 as qtm :: qtms) (Single (qtm',n)) =
   132       if qtm = qtm' then SINGLE (qtm, add a qtms n)
   169       if equalQterm qtm qtm' then Single (qtm, add a qtms n)
   133       else add a input1 (add n [qtm'] (MULTIPLE (NONE, NameArityMap.new ())))
   170       else add a input1 (add n [qtm'] (Multiple (NONE, NameArityMap.new ())))
   134     | add a (VAR :: qtms) (MULTIPLE (vs,fs)) =
   171     | add a (Var :: qtms) (Multiple (vs,fs)) =
   135       MULTIPLE (SOME (oadd a qtms vs), fs)
   172       Multiple (SOME (oadd a qtms vs), fs)
   136     | add a (FN (f,l) :: qtms) (MULTIPLE (vs,fs)) =
   173     | add a (Fn (f,l) :: qtms) (Multiple (vs,fs)) =
   137       let
   174       let
   138         val n = NameArityMap.peek fs f
   175         val n = NameArityMap.peek fs f
   139       in
   176       in
   140         MULTIPLE (vs, NameArityMap.insert fs (f, oadd a (l @ qtms) n))
   177         Multiple (vs, NameArityMap.insert fs (f, oadd a (l @ qtms) n))
   141       end
   178       end
   142     | add _ _ _ = raise Bug "TermNet.insert: Match"
   179     | add _ _ _ = raise Bug "TermNet.insert: Match"
   143 
   180 
   144   and oadd a qtms NONE = singles qtms a
   181   and oadd a qtms NONE = singles qtms a
   145     | oadd a qtms (SOME n) = add a qtms n;
   182     | oadd a qtms (SOME n) = add a qtms n;
   146 
   183 
   147   fun ins a qtm (i,n) = SOME (i + 1, oadd (RESULT [a]) [qtm] n);
   184   fun ins a qtm (i,n) = SOME (i + 1, oadd (Result [a]) [qtm] n);
   148 in
   185 in
   149   fun insert (NET (p,k,n)) (tm,a) =
   186   fun insert (Net (p,k,n)) (tm,a) =
   150       NET (p, k + 1, ins (k,a) (termToQterm tm) (pre n))
   187       Net (p, k + 1, ins (k,a) (termToQterm tm) (pre n))
   151       handle Error _ => raise Bug "TermNet.insert: should never fail";
   188       handle Error _ => raise Bug "TermNet.insert: should never fail";
   152 end;
   189 end;
   153 
   190 
   154 fun fromList parm l = foldl (fn (tm_a,n) => insert n tm_a) (new parm) l;
   191 fun fromList parm l = foldl (fn (tm_a,n) => insert n tm_a) (new parm) l;
   155 
   192 
   156 fun filter pred =
   193 fun filter pred =
   157     let
   194     let
   158       fun filt (RESULT l) =
   195       fun filt (Result l) =
   159           (case List.filter (fn (_,a) => pred a) l of
   196           (case List.filter (fn (_,a) => pred a) l of
   160              [] => NONE
   197              [] => NONE
   161            | l => SOME (RESULT l))
   198            | l => SOME (Result l))
   162         | filt (SINGLE (qtm,n)) =
   199         | filt (Single (qtm,n)) =
   163           (case filt n of
   200           (case filt n of
   164              NONE => NONE
   201              NONE => NONE
   165            | SOME n => SOME (SINGLE (qtm,n)))
   202            | SOME n => SOME (Single (qtm,n)))
   166         | filt (MULTIPLE (vs,fs)) =
   203         | filt (Multiple (vs,fs)) =
   167           let
   204           let
   168             val vs = Option.mapPartial filt vs
   205             val vs = Option.mapPartial filt vs
   169 
   206 
   170             val fs = NameArityMap.mapPartial (fn (_,n) => filt n) fs
   207             val fs = NameArityMap.mapPartial (fn (_,n) => filt n) fs
   171           in
   208           in
   172             if not (Option.isSome vs) andalso NameArityMap.null fs then NONE
   209             if not (Option.isSome vs) andalso NameArityMap.null fs then NONE
   173             else SOME (MULTIPLE (vs,fs))
   210             else SOME (Multiple (vs,fs))
   174           end
   211           end
   175     in
   212     in
   176       fn net as NET (_,_,NONE) => net
   213       fn net as Net (_,_,NONE) => net
   177        | NET (p, k, SOME (_,n)) => NET (p, k, netSize (filt n))
   214        | Net (p, k, SOME (_,n)) => Net (p, k, netSize (filt n))
   178     end
   215     end
   179     handle Error _ => raise Bug "TermNet.filter: should never fail";
   216     handle Error _ => raise Bug "TermNet.filter: should never fail";
   180 
   217 
   181 fun toString net = "TermNet[" ^ Int.toString (size net) ^ "]";
   218 fun toString net = "TermNet[" ^ Int.toString (size net) ^ "]";
   182 
   219 
   187 local
   224 local
   188   fun norm (0 :: ks, (f as (_,n)) :: fs, qtms) =
   225   fun norm (0 :: ks, (f as (_,n)) :: fs, qtms) =
   189       let
   226       let
   190         val (a,qtms) = revDivide qtms n
   227         val (a,qtms) = revDivide qtms n
   191       in
   228       in
   192         addQterm (FN (f,a)) (ks,fs,qtms)
   229         addQterm (Fn (f,a)) (ks,fs,qtms)
   193       end
   230       end
   194     | norm stack = stack
   231     | norm stack = stack
   195 
   232 
   196   and addQterm qtm (ks,fs,qtms) =
   233   and addQterm qtm (ks,fs,qtms) =
   197       let
   234       let
   201       end
   238       end
   202 
   239 
   203   and addFn (f as (_,n)) (ks,fs,qtms) = norm (n :: ks, f :: fs, qtms);
   240   and addFn (f as (_,n)) (ks,fs,qtms) = norm (n :: ks, f :: fs, qtms);
   204 in
   241 in
   205   val stackEmpty = ([],[],[]);
   242   val stackEmpty = ([],[],[]);
   206     
   243 
   207   val stackAddQterm = addQterm;
   244   val stackAddQterm = addQterm;
   208 
   245 
   209   val stackAddFn = addFn;
   246   val stackAddFn = addFn;
   210 
   247 
   211   fun stackValue ([],[],[qtm]) = qtm
   248   fun stackValue ([],[],[qtm]) = qtm
   214 
   251 
   215 local
   252 local
   216   fun fold _ acc [] = acc
   253   fun fold _ acc [] = acc
   217     | fold inc acc ((0,stack,net) :: rest) =
   254     | fold inc acc ((0,stack,net) :: rest) =
   218       fold inc (inc (stackValue stack, net, acc)) rest
   255       fold inc (inc (stackValue stack, net, acc)) rest
   219     | fold inc acc ((n, stack, SINGLE (qtm,net)) :: rest) =
   256     | fold inc acc ((n, stack, Single (qtm,net)) :: rest) =
   220       fold inc acc ((n - 1, stackAddQterm qtm stack, net) :: rest)
   257       fold inc acc ((n - 1, stackAddQterm qtm stack, net) :: rest)
   221     | fold inc acc ((n, stack, MULTIPLE (v,fns)) :: rest) =
   258     | fold inc acc ((n, stack, Multiple (v,fns)) :: rest) =
   222       let
   259       let
   223         val n = n - 1
   260         val n = n - 1
   224 
   261 
   225         val rest =
   262         val rest =
   226             case v of
   263             case v of
   227               NONE => rest
   264               NONE => rest
   228             | SOME net => (n, stackAddQterm VAR stack, net) :: rest
   265             | SOME net => (n, stackAddQterm Var stack, net) :: rest
   229 
   266 
   230         fun getFns (f as (_,k), net, x) =
   267         fun getFns (f as (_,k), net, x) =
   231             (k + n, stackAddFn f stack, net) :: x
   268             (k + n, stackAddFn f stack, net) :: x
   232       in
   269       in
   233         fold inc acc (NameArityMap.foldr getFns rest fns)
   270         fold inc acc (NameArityMap.foldr getFns rest fns)
   238 end;
   275 end;
   239 
   276 
   240 fun foldEqualTerms pat inc acc =
   277 fun foldEqualTerms pat inc acc =
   241     let
   278     let
   242       fun fold ([],net) = inc (pat,net,acc)
   279       fun fold ([],net) = inc (pat,net,acc)
   243         | fold (pat :: pats, SINGLE (qtm,net)) =
   280         | fold (pat :: pats, Single (qtm,net)) =
   244           if pat = qtm then fold (pats,net) else acc
   281           if equalQterm pat qtm then fold (pats,net) else acc
   245         | fold (VAR :: pats, MULTIPLE (v,_)) =
   282         | fold (Var :: pats, Multiple (v,_)) =
   246           (case v of NONE => acc | SOME net => fold (pats,net))
   283           (case v of NONE => acc | SOME net => fold (pats,net))
   247         | fold (FN (f,a) :: pats, MULTIPLE (_,fns)) =
   284         | fold (Fn (f,a) :: pats, Multiple (_,fns)) =
   248           (case NameArityMap.peek fns f of
   285           (case NameArityMap.peek fns f of
   249              NONE => acc
   286              NONE => acc
   250            | SOME net => fold (a @ pats, net))
   287            | SOME net => fold (a @ pats, net))
   251         | fold _ = raise Bug "TermNet.foldEqualTerms.fold";
   288         | fold _ = raise Bug "TermNet.foldEqualTerms.fold";
   252     in
   289     in
   255 
   292 
   256 local
   293 local
   257   fun fold _ acc [] = acc
   294   fun fold _ acc [] = acc
   258     | fold inc acc (([],stack,net) :: rest) =
   295     | fold inc acc (([],stack,net) :: rest) =
   259       fold inc (inc (stackValue stack, net, acc)) rest
   296       fold inc (inc (stackValue stack, net, acc)) rest
   260     | fold inc acc ((VAR :: pats, stack, net) :: rest) =
   297     | fold inc acc ((Var :: pats, stack, net) :: rest) =
   261       let
   298       let
   262         fun harvest (qtm,n,l) = (pats, stackAddQterm qtm stack, n) :: l
   299         fun harvest (qtm,n,l) = (pats, stackAddQterm qtm stack, n) :: l
   263       in
   300       in
   264         fold inc acc (foldTerms harvest rest net)
   301         fold inc acc (foldTerms harvest rest net)
   265       end
   302       end
   266     | fold inc acc ((pat :: pats, stack, SINGLE (qtm,net)) :: rest) =
   303     | fold inc acc ((pat :: pats, stack, Single (qtm,net)) :: rest) =
   267       (case unifyQtermQterm pat qtm of
   304       (case unifyQtermQterm pat qtm of
   268          NONE => fold inc acc rest
   305          NONE => fold inc acc rest
   269        | SOME qtm =>
   306        | SOME qtm =>
   270          fold inc acc ((pats, stackAddQterm qtm stack, net) :: rest))
   307          fold inc acc ((pats, stackAddQterm qtm stack, net) :: rest))
   271     | fold
   308     | fold
   272         inc acc
   309         inc acc
   273         (((pat as FN (f,a)) :: pats, stack, MULTIPLE (v,fns)) :: rest) =
   310         (((pat as Fn (f,a)) :: pats, stack, Multiple (v,fns)) :: rest) =
   274       let
   311       let
   275         val rest =
   312         val rest =
   276             case v of
   313             case v of
   277               NONE => rest
   314               NONE => rest
   278             | SOME net => (pats, stackAddQterm pat stack, net) :: rest
   315             | SOME net => (pats, stackAddQterm pat stack, net) :: rest
   305   fun finally parm l = map snd (fifoize parm l);
   342   fun finally parm l = map snd (fifoize parm l);
   306 end;
   343 end;
   307 
   344 
   308 local
   345 local
   309   fun mat acc [] = acc
   346   fun mat acc [] = acc
   310     | mat acc ((RESULT l, []) :: rest) = mat (l @ acc) rest
   347     | mat acc ((Result l, []) :: rest) = mat (l @ acc) rest
   311     | mat acc ((SINGLE (qtm,n), tm :: tms) :: rest) =
   348     | mat acc ((Single (qtm,n), tm :: tms) :: rest) =
   312       mat acc (if matchQtermTerm qtm tm then (n,tms) :: rest else rest)
   349       mat acc (if matchQtermTerm qtm tm then (n,tms) :: rest else rest)
   313     | mat acc ((MULTIPLE (vs,fs), tm :: tms) :: rest) =
   350     | mat acc ((Multiple (vs,fs), tm :: tms) :: rest) =
   314       let
   351       let
   315         val rest = case vs of NONE => rest | SOME n => (n,tms) :: rest
   352         val rest = case vs of NONE => rest | SOME n => (n,tms) :: rest
   316 
   353 
   317         val rest =
   354         val rest =
   318             case tm of
   355             case tm of
   324       in
   361       in
   325         mat acc rest
   362         mat acc rest
   326       end
   363       end
   327     | mat _ _ = raise Bug "TermNet.match: Match";
   364     | mat _ _ = raise Bug "TermNet.match: Match";
   328 in
   365 in
   329   fun match (NET (_,_,NONE)) _ = []
   366   fun match (Net (_,_,NONE)) _ = []
   330     | match (NET (p, _, SOME (_,n))) tm =
   367     | match (Net (p, _, SOME (_,n))) tm =
   331       finally p (mat [] [(n,[tm])])
   368       finally p (mat [] [(n,[tm])])
   332       handle Error _ => raise Bug "TermNet.match: should never fail";
   369       handle Error _ => raise Bug "TermNet.match: should never fail";
   333 end;
   370 end;
   334 
   371 
   335 local
   372 local
   337       (NameMap.insert qsub (v,qtm), net, tms) :: rest;
   374       (NameMap.insert qsub (v,qtm), net, tms) :: rest;
   338 
   375 
   339   fun seenInc qsub tms (_,net,rest) = (qsub,net,tms) :: rest;
   376   fun seenInc qsub tms (_,net,rest) = (qsub,net,tms) :: rest;
   340 
   377 
   341   fun mat acc [] = acc
   378   fun mat acc [] = acc
   342     | mat acc ((_, RESULT l, []) :: rest) = mat (l @ acc) rest
   379     | mat acc ((_, Result l, []) :: rest) = mat (l @ acc) rest
   343     | mat acc ((qsub, SINGLE (qtm,net), tm :: tms) :: rest) =
   380     | mat acc ((qsub, Single (qtm,net), tm :: tms) :: rest) =
   344       (case matchTermQterm qsub tm qtm of
   381       (case matchTermQterm qsub tm qtm of
   345          NONE => mat acc rest
   382          NONE => mat acc rest
   346        | SOME qsub => mat acc ((qsub,net,tms) :: rest))
   383        | SOME qsub => mat acc ((qsub,net,tms) :: rest))
   347     | mat acc ((qsub, net as MULTIPLE _, Term.Var v :: tms) :: rest) =
   384     | mat acc ((qsub, net as Multiple _, Term.Var v :: tms) :: rest) =
   348       (case NameMap.peek qsub v of
   385       (case NameMap.peek qsub v of
   349          NONE => mat acc (foldTerms (unseenInc qsub v tms) rest net)
   386          NONE => mat acc (foldTerms (unseenInc qsub v tms) rest net)
   350        | SOME qtm => mat acc (foldEqualTerms qtm (seenInc qsub tms) rest net))
   387        | SOME qtm => mat acc (foldEqualTerms qtm (seenInc qsub tms) rest net))
   351     | mat acc ((qsub, MULTIPLE (_,fns), Term.Fn (f,a) :: tms) :: rest) =
   388     | mat acc ((qsub, Multiple (_,fns), Term.Fn (f,a) :: tms) :: rest) =
   352       let
   389       let
   353         val rest =
   390         val rest =
   354             case NameArityMap.peek fns (f, length a) of
   391             case NameArityMap.peek fns (f, length a) of
   355               NONE => rest
   392               NONE => rest
   356             | SOME net => (qsub, net, a @ tms) :: rest
   393             | SOME net => (qsub, net, a @ tms) :: rest
   357       in
   394       in
   358         mat acc rest
   395         mat acc rest
   359       end
   396       end
   360     | mat _ _ = raise Bug "TermNet.matched.mat";
   397     | mat _ _ = raise Bug "TermNet.matched.mat";
   361 in
   398 in
   362   fun matched (NET (_,_,NONE)) _ = []
   399   fun matched (Net (_,_,NONE)) _ = []
   363     | matched (NET (parm, _, SOME (_,net))) tm =
   400     | matched (Net (parm, _, SOME (_,net))) tm =
   364       finally parm (mat [] [(NameMap.new (), net, [tm])])
   401       finally parm (mat [] [(NameMap.new (), net, [tm])])
   365       handle Error _ => raise Bug "TermNet.matched: should never fail";
   402       handle Error _ => raise Bug "TermNet.matched: should never fail";
   366 end;
   403 end;
   367 
   404 
   368 local
   405 local
   369   fun inc qsub v tms (qtm,net,rest) =
   406   fun inc qsub v tms (qtm,net,rest) =
   370       (NameMap.insert qsub (v,qtm), net, tms) :: rest;
   407       (NameMap.insert qsub (v,qtm), net, tms) :: rest;
   371 
   408 
   372   fun mat acc [] = acc
   409   fun mat acc [] = acc
   373     | mat acc ((_, RESULT l, []) :: rest) = mat (l @ acc) rest
   410     | mat acc ((_, Result l, []) :: rest) = mat (l @ acc) rest
   374     | mat acc ((qsub, SINGLE (qtm,net), tm :: tms) :: rest) =
   411     | mat acc ((qsub, Single (qtm,net), tm :: tms) :: rest) =
   375       (case unifyQtermTerm qsub qtm tm of
   412       (case unifyQtermTerm qsub qtm tm of
   376          NONE => mat acc rest
   413          NONE => mat acc rest
   377        | SOME qsub => mat acc ((qsub,net,tms) :: rest))
   414        | SOME qsub => mat acc ((qsub,net,tms) :: rest))
   378     | mat acc ((qsub, net as MULTIPLE _, Term.Var v :: tms) :: rest) =
   415     | mat acc ((qsub, net as Multiple _, Term.Var v :: tms) :: rest) =
   379       (case NameMap.peek qsub v of
   416       (case NameMap.peek qsub v of
   380          NONE => mat acc (foldTerms (inc qsub v tms) rest net)
   417          NONE => mat acc (foldTerms (inc qsub v tms) rest net)
   381        | SOME qtm => mat acc (foldUnifiableTerms qtm (inc qsub v tms) rest net))
   418        | SOME qtm => mat acc (foldUnifiableTerms qtm (inc qsub v tms) rest net))
   382     | mat acc ((qsub, MULTIPLE (v,fns), Term.Fn (f,a) :: tms) :: rest) =
   419     | mat acc ((qsub, Multiple (v,fns), Term.Fn (f,a) :: tms) :: rest) =
   383       let
   420       let
   384         val rest = case v of NONE => rest | SOME net => (qsub,net,tms) :: rest
   421         val rest = case v of NONE => rest | SOME net => (qsub,net,tms) :: rest
   385 
   422 
   386         val rest =
   423         val rest =
   387             case NameArityMap.peek fns (f, length a) of
   424             case NameArityMap.peek fns (f, length a) of
   390       in
   427       in
   391         mat acc rest
   428         mat acc rest
   392       end
   429       end
   393     | mat _ _ = raise Bug "TermNet.unify.mat";
   430     | mat _ _ = raise Bug "TermNet.unify.mat";
   394 in
   431 in
   395   fun unify (NET (_,_,NONE)) _ = []
   432   fun unify (Net (_,_,NONE)) _ = []
   396     | unify (NET (parm, _, SOME (_,net))) tm =
   433     | unify (Net (parm, _, SOME (_,net))) tm =
   397       finally parm (mat [] [(NameMap.new (), net, [tm])])
   434       finally parm (mat [] [(NameMap.new (), net, [tm])])
   398       handle Error _ => raise Bug "TermNet.unify: should never fail";
   435       handle Error _ => raise Bug "TermNet.unify: should never fail";
   399 end;
   436 end;
   400 
   437 
   401 (* ------------------------------------------------------------------------- *)
   438 (* ------------------------------------------------------------------------- *)
   402 (* Pretty printing.                                                          *)
   439 (* Pretty printing.                                                          *)
   403 (* ------------------------------------------------------------------------- *)
   440 (* ------------------------------------------------------------------------- *)
   404 
   441 
   405 local
   442 local
   406   fun inc (qtm, RESULT l, acc) =
   443   fun inc (qtm, Result l, acc) =
   407       foldl (fn ((n,a),acc) => (n,(qtm,a)) :: acc) acc l
   444       foldl (fn ((n,a),acc) => (n,(qtm,a)) :: acc) acc l
   408     | inc _ = raise Bug "TermNet.pp.inc";
   445     | inc _ = raise Bug "TermNet.pp.inc";
   409       
   446 
   410   fun toList (NET (_,_,NONE)) = []
   447   fun toList (Net (_,_,NONE)) = []
   411     | toList (NET (parm, _, SOME (_,net))) =
   448     | toList (Net (parm, _, SOME (_,net))) =
   412       finally parm (foldTerms inc [] net);
   449       finally parm (foldTerms inc [] net);
   413 in
   450 in
   414   fun pp ppA =
   451   fun pp ppA =
   415       Parser.ppMap toList (Parser.ppList (Parser.ppBinop " |->" ppQterm ppA));
   452       Print.ppMap toList (Print.ppList (Print.ppOp2 " |->" ppQterm ppA));
   416 end;
   453 end;
   417 
   454 
   418 end
   455 end