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