src/Tools/Metis/src/Term.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
(* FIRST ORDER LOGIC TERMS                                                   *)
39349
2d0a4361c3ef change license, with Joe Hurd's permission
blanchet
parents: 39348
diff changeset
     3
(* Copyright (c) 2001 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 Term :> Term =
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
(* A type of first order logic terms.                                        *)
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
type var = Name.name;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    16
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    17
type functionName = Name.name;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    18
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    19
type function = functionName * int;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    20
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    21
type const = functionName;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    22
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    23
datatype term =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    24
    Var of Name.name
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    25
  | Fn of Name.name * term list;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    26
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    27
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    28
(* Constructors and destructors.                                             *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    29
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    30
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    31
(* Variables *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    32
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    33
fun destVar (Var v) = v
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    34
  | destVar (Fn _) = raise Error "destVar";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    35
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    36
val isVar = can destVar;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    37
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    38
fun equalVar v (Var v') = Name.equal v v'
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    39
  | equalVar _ _ = false;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    40
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    41
(* Functions *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    42
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    43
fun destFn (Fn f) = f
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    44
  | destFn (Var _) = raise Error "destFn";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    45
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    46
val isFn = can destFn;
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 fnName tm = fst (destFn tm);
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 fnArguments tm = snd (destFn tm);
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 fnArity tm = length (fnArguments tm);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    53
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    54
fun fnFunction tm = (fnName tm, fnArity tm);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    55
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    56
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    57
  fun func fs [] = fs
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    58
    | func fs (Var _ :: tms) = func fs tms
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    59
    | func fs (Fn (n,l) :: tms) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    60
      func (NameAritySet.add fs (n, length l)) (l @ tms);
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 functions tm = func NameAritySet.empty [tm];
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 func fs [] = fs
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    67
    | func fs (Var _ :: tms) = func fs tms
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    68
    | func fs (Fn (n,l) :: tms) = func (NameSet.add fs n) (l @ tms);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    69
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    70
  fun functionNames tm = func NameSet.empty [tm];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    71
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    72
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    73
(* Constants *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    74
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    75
fun mkConst c = (Fn (c, []));
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    76
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    77
fun destConst (Fn (c, [])) = c
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    78
  | destConst _ = raise Error "destConst";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    79
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    80
val isConst = can destConst;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    81
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    82
(* Binary functions *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    83
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    84
fun mkBinop f (a,b) = Fn (f,[a,b]);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    85
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    86
fun destBinop f (Fn (x,[a,b])) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    87
    if Name.equal x f then (a,b) else raise Error "Term.destBinop: wrong binop"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    88
  | destBinop _ _ = raise Error "Term.destBinop: not a binop";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    89
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    90
fun isBinop f = can (destBinop f);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    91
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    92
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    93
(* The size of a term in symbols.                                            *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    94
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    95
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    96
val VAR_SYMBOLS = 1;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    97
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    98
val FN_SYMBOLS = 1;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
    99
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   100
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   101
  fun sz n [] = n
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   102
    | sz n (Var _ :: tms) = sz (n + VAR_SYMBOLS) tms
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   103
    | sz n (Fn (func,args) :: tms) = sz (n + FN_SYMBOLS) (args @ tms);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   104
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   105
  fun symbols tm = sz 0 [tm];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   106
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   107
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   108
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   109
(* A total comparison function for terms.                                    *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   110
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   111
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   112
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   113
  fun cmp [] [] = EQUAL
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   114
    | cmp (tm1 :: tms1) (tm2 :: tms2) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   115
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   116
        val tm1_tm2 = (tm1,tm2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   117
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   118
        if Portable.pointerEqual tm1_tm2 then cmp tms1 tms2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   119
        else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   120
          case tm1_tm2 of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   121
            (Var v1, Var v2) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   122
            (case Name.compare (v1,v2) of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   123
               LESS => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   124
             | EQUAL => cmp tms1 tms2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   125
             | GREATER => GREATER)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   126
          | (Var _, Fn _) => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   127
          | (Fn _, Var _) => GREATER
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   128
          | (Fn (f1,a1), Fn (f2,a2)) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   129
            (case Name.compare (f1,f2) of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   130
               LESS => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   131
             | EQUAL =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   132
               (case Int.compare (length a1, length a2) of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   133
                  LESS => LESS
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   134
                | EQUAL => cmp (a1 @ tms1) (a2 @ tms2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   135
                | GREATER => GREATER)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   136
             | GREATER => GREATER)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   137
      end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   138
    | cmp _ _ = raise Bug "Term.compare";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   139
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   140
  fun compare (tm1,tm2) = cmp [tm1] [tm2];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   141
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   142
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   143
fun equal tm1 tm2 = compare (tm1,tm2) = EQUAL;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   144
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   145
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   146
(* Subterms.                                                                 *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   147
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   148
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   149
type path = int list;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   150
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   151
fun subterm tm [] = tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   152
  | subterm (Var _) (_ :: _) = raise Error "Term.subterm: Var"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   153
  | subterm (Fn (_,tms)) (h :: t) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   154
    if h >= length tms then raise Error "Term.replace: Fn"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   155
    else subterm (List.nth (tms,h)) t;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   156
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   157
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   158
  fun subtms [] acc = acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   159
    | subtms ((path,tm) :: rest) acc =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   160
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   161
        fun f (n,arg) = (n :: path, arg)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   162
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   163
        val acc = (rev path, tm) :: acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   164
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   165
        case tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   166
          Var _ => subtms rest acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   167
        | Fn (_,args) => subtms (map f (enumerate args) @ rest) acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   168
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   169
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   170
  fun subterms tm = subtms [([],tm)] [];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   171
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   172
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   173
fun replace tm ([],res) = if equal res tm then tm else res
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   174
  | replace tm (h :: t, res) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   175
    case tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   176
      Var _ => raise Error "Term.replace: Var"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   177
    | Fn (func,tms) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   178
      if h >= length tms then raise Error "Term.replace: Fn"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   179
      else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   180
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   181
          val arg = List.nth (tms,h)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   182
          val arg' = replace arg (t,res)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   183
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   184
          if Portable.pointerEqual (arg',arg) then tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   185
          else Fn (func, updateNth (h,arg') tms)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   186
        end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   187
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   188
fun find pred =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   189
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   190
      fun search [] = NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   191
        | search ((path,tm) :: rest) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   192
          if pred tm then SOME (rev path)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   193
          else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   194
            case tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   195
              Var _ => search rest
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   196
            | Fn (_,a) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   197
              let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   198
                val subtms = map (fn (i,t) => (i :: path, t)) (enumerate a)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   199
              in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   200
                search (subtms @ rest)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   201
              end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   202
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   203
      fn tm => search [([],tm)]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   204
    end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   205
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   206
val ppPath = Print.ppList Print.ppInt;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   207
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   208
val pathToString = Print.toString ppPath;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   209
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   210
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   211
(* Free variables.                                                           *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   212
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   213
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   214
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   215
  fun free _ [] = false
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   216
    | free v (Var w :: tms) = Name.equal v w orelse free v tms
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   217
    | free v (Fn (_,args) :: tms) = free v (args @ tms);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   218
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   219
  fun freeIn v tm = free v [tm];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   220
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   221
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   222
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   223
  fun free vs [] = vs
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   224
    | free vs (Var v :: tms) = free (NameSet.add vs v) tms
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   225
    | free vs (Fn (_,args) :: tms) = free vs (args @ tms);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   226
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   227
  val freeVarsList = free NameSet.empty;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   228
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   229
  fun freeVars tm = freeVarsList [tm];
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
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   232
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   233
(* Fresh variables.                                                          *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   234
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   235
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   236
fun newVar () = Var (Name.newName ());
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   237
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   238
fun newVars n = map Var (Name.newNames n);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   239
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   240
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   241
  fun avoidAcceptable avoid n = not (NameSet.member n avoid);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   242
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   243
  fun variantPrime avoid = Name.variantPrime (avoidAcceptable avoid);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   244
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   245
  fun variantNum avoid = Name.variantNum (avoidAcceptable avoid);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   246
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   247
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   248
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   249
(* Special support for terms with type annotations.                          *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   250
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   251
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   252
val hasTypeFunctionName = Name.fromString ":";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   253
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   254
val hasTypeFunction = (hasTypeFunctionName,2);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   255
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   256
fun destFnHasType ((f,a) : functionName * term list) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   257
    if not (Name.equal f hasTypeFunctionName) then
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   258
      raise Error "Term.destFnHasType"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   259
    else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   260
      case a of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   261
        [tm,ty] => (tm,ty)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   262
      | _ => raise Error "Term.destFnHasType";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   263
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   264
val isFnHasType = can destFnHasType;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   265
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   266
fun isTypedVar tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   267
    case tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   268
      Var _ => true
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   269
    | Fn func =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   270
      case total destFnHasType func of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   271
        SOME (Var _, _) => true
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   272
      | _ => false;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   273
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   274
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   275
  fun sz n [] = n
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   276
    | sz n (tm :: tms) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   277
      case tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   278
        Var _ => sz (n + 1) tms
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   279
      | Fn func =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   280
        case total destFnHasType func of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   281
          SOME (tm,_) => sz n (tm :: tms)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   282
        | NONE =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   283
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   284
            val (_,a) = func
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   285
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   286
            sz (n + 1) (a @ tms)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   287
          end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   288
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   289
  fun typedSymbols tm = sz 0 [tm];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   290
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   291
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   292
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   293
  fun subtms [] acc = acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   294
    | subtms ((path,tm) :: rest) acc =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   295
      case tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   296
        Var _ => subtms rest acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   297
      | Fn func =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   298
        case total destFnHasType func of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   299
          SOME (t,_) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   300
          (case t of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   301
             Var _ => subtms rest acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   302
           | Fn _ =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   303
             let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   304
               val acc = (rev path, tm) :: acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   305
               val rest = (0 :: path, t) :: rest
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   306
             in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   307
               subtms rest acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   308
             end)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   309
        | NONE =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   310
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   311
            fun f (n,arg) = (n :: path, arg)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   312
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   313
            val (_,args) = func
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   314
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   315
            val acc = (rev path, tm) :: acc
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 = map f (enumerate args) @ rest
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   318
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   319
            subtms rest acc
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   320
          end;
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
  fun nonVarTypedSubterms tm = subtms [([],tm)] [];
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
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   325
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   326
(* Special support for terms with an explicit function application operator. *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   327
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   328
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   329
val appName = Name.fromString ".";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   330
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   331
fun mkFnApp (fTm,aTm) = (appName, [fTm,aTm]);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   332
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   333
fun mkApp f_a = Fn (mkFnApp f_a);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   334
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   335
fun destFnApp ((f,a) : Name.name * term list) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   336
    if not (Name.equal f appName) then raise Error "Term.destFnApp"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   337
    else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   338
      case a of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   339
        [fTm,aTm] => (fTm,aTm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   340
      | _ => raise Error "Term.destFnApp";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   341
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   342
val isFnApp = can destFnApp;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   343
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   344
fun destApp tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   345
    case tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   346
      Var _ => raise Error "Term.destApp"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   347
    | Fn func => destFnApp func;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   348
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   349
val isApp = can destApp;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   350
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   351
fun listMkApp (f,l) = foldl mkApp f l;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   352
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   353
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   354
  fun strip tms tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   355
      case total destApp tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   356
        SOME (f,a) => strip (a :: tms) f
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   357
      | NONE => (tm,tms);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   358
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   359
  fun stripApp tm = strip [] tm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   360
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   361
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   362
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   363
(* Parsing and pretty printing.                                              *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   364
(* ------------------------------------------------------------------------- *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   365
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   366
(* Operators parsed and printed infix *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   367
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   368
val infixes =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   369
    (ref o Print.Infixes)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   370
      [(* ML symbols *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   371
       {token = " / ", precedence = 7, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   372
       {token = " div ", precedence = 7, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   373
       {token = " mod ", precedence = 7, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   374
       {token = " * ", precedence = 7, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   375
       {token = " + ", precedence = 6, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   376
       {token = " - ", precedence = 6, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   377
       {token = " ^ ", precedence = 6, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   378
       {token = " @ ", precedence = 5, leftAssoc = false},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   379
       {token = " :: ", precedence = 5, leftAssoc = false},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   380
       {token = " = ", precedence = 4, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   381
       {token = " <> ", precedence = 4, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   382
       {token = " <= ", precedence = 4, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   383
       {token = " < ", precedence = 4, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   384
       {token = " >= ", precedence = 4, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   385
       {token = " > ", precedence = 4, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   386
       {token = " o ", precedence = 3, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   387
       {token = " -> ", precedence = 2, leftAssoc = false},  (* inferred prec *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   388
       {token = " : ", precedence = 1, leftAssoc = false},  (* inferred prec *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   389
       {token = ", ", precedence = 0, leftAssoc = false},  (* inferred prec *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   390
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   391
       (* Logical connectives *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   392
       {token = " /\\ ", precedence = ~1, leftAssoc = false},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   393
       {token = " \\/ ", precedence = ~2, leftAssoc = false},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   394
       {token = " ==> ", precedence = ~3, leftAssoc = false},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   395
       {token = " <=> ", precedence = ~4, leftAssoc = false},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   396
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   397
       (* Other symbols *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   398
       {token = " . ", precedence = 9, leftAssoc = true},  (* function app *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   399
       {token = " ** ", precedence = 8, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   400
       {token = " ++ ", precedence = 6, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   401
       {token = " -- ", precedence = 6, leftAssoc = true},
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   402
       {token = " == ", precedence = 4, leftAssoc = true}];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   403
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   404
(* The negation symbol *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   405
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   406
val negation : string ref = ref "~";
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   407
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   408
(* Binder symbols *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   409
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   410
val binders : string list ref = ref ["\\","!","?","?!"];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   411
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   412
(* Bracket symbols *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   413
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   414
val brackets : (string * string) list ref = ref [("[","]"),("{","}")];
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   415
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   416
(* Pretty printing *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   417
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   418
fun pp inputTerm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   419
    let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   420
      val quants = !binders
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   421
      and iOps = !infixes
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   422
      and neg = !negation
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   423
      and bracks = !brackets
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   424
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   425
      val bracks = map (fn (b1,b2) => (b1 ^ b2, b1, b2)) bracks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   426
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   427
      val bTokens = map #2 bracks @ map #3 bracks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   428
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   429
      val iTokens = Print.tokensInfixes iOps
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   430
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   431
      fun destI tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   432
          case tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   433
            Fn (f,[a,b]) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   434
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   435
              val f = Name.toString f
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   436
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   437
              if StringSet.member f iTokens then SOME (f,a,b) else NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   438
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   439
          | _ => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   440
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   441
      val iPrinter = Print.ppInfixes iOps destI
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   442
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   443
      val specialTokens =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   444
          StringSet.addList iTokens (neg :: quants @ ["$","(",")"] @ bTokens)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   445
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   446
      fun vName bv s = StringSet.member s bv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   447
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   448
      fun checkVarName bv n =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   449
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   450
            val s = Name.toString n
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   451
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   452
            if vName bv s then s else "$" ^ s
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
      fun varName bv = Print.ppMap (checkVarName bv) Print.ppString
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   456
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   457
      fun checkFunctionName bv n =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   458
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   459
            val s = Name.toString n
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   460
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   461
            if StringSet.member s specialTokens orelse vName bv s then
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   462
              "(" ^ s ^ ")"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   463
            else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   464
              s
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   465
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   466
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   467
      fun functionName bv = Print.ppMap (checkFunctionName bv) Print.ppString
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   468
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   469
      fun isI tm = Option.isSome (destI tm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   470
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   471
      fun stripNeg tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   472
          case tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   473
            Fn (f,[a]) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   474
            if Name.toString f <> neg then (0,tm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   475
            else let val (n,tm) = stripNeg a in (n + 1, tm) end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   476
          | _ => (0,tm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   477
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   478
      val destQuant =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   479
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   480
            fun dest q (Fn (q', [Var v, body])) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   481
                if Name.toString q' <> q then NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   482
                else
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   483
                  (case dest q body of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   484
                     NONE => SOME (q,v,[],body)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   485
                   | SOME (_,v',vs,body) => SOME (q, v, v' :: vs, body))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   486
              | dest _ _ = NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   487
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   488
            fn tm => Useful.first (fn q => dest q tm) quants
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   489
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   490
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   491
      fun isQuant tm = Option.isSome (destQuant tm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   492
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   493
      fun destBrack (Fn (b,[tm])) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   494
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   495
            val s = Name.toString b
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   496
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   497
            case List.find (fn (n,_,_) => n = s) bracks of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   498
              NONE => NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   499
            | SOME (_,b1,b2) => SOME (b1,tm,b2)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   500
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   501
        | destBrack _ = NONE
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   502
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   503
      fun isBrack tm = Option.isSome (destBrack tm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   504
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   505
      fun functionArgument bv tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   506
          Print.sequence
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   507
            (Print.addBreak 1)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   508
            (if isBrack tm then customBracket bv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   509
             else if isVar tm orelse isConst tm then basic bv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   510
             else bracket bv tm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   511
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   512
      and basic bv (Var v) = varName bv v
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   513
        | basic bv (Fn (f,args)) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   514
          Print.blockProgram Print.Inconsistent 2
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   515
            (functionName bv f :: map (functionArgument bv) args)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   516
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   517
      and customBracket bv tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   518
          case destBrack tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   519
            SOME (b1,tm,b2) => Print.ppBracket b1 b2 (term bv) tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   520
          | NONE => basic bv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   521
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   522
      and innerQuant bv tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   523
          case destQuant tm of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   524
            NONE => term bv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   525
          | SOME (q,v,vs,tm) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   526
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   527
              val bv = StringSet.addList bv (map Name.toString (v :: vs))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   528
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   529
              Print.program
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   530
                [Print.addString q,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   531
                 varName bv v,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   532
                 Print.program
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   533
                   (map (Print.sequence (Print.addBreak 1) o varName bv) vs),
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   534
                 Print.addString ".",
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   535
                 Print.addBreak 1,
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   536
                 innerQuant bv tm]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   537
            end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   538
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   539
      and quantifier bv tm =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   540
          if not (isQuant tm) then customBracket bv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   541
          else Print.block Print.Inconsistent 2 (innerQuant bv tm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   542
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   543
      and molecule bv (tm,r) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   544
          let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   545
            val (n,tm) = stripNeg tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   546
          in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   547
            Print.blockProgram Print.Inconsistent n
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   548
              [Print.duplicate n (Print.addString neg),
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   549
               if isI tm orelse (r andalso isQuant tm) then bracket bv tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   550
               else quantifier bv tm]
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   551
          end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   552
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   553
      and term bv tm = iPrinter (molecule bv) (tm,false)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   554
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   555
      and bracket bv tm = Print.ppBracket "(" ")" (term bv) tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   556
    in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   557
      term StringSet.empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   558
    end inputTerm;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   559
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   560
val toString = Print.toString pp;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   561
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   562
(* Parsing *)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   563
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   564
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   565
  open Parse;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   566
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   567
  infixr 9 >>++
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   568
  infixr 8 ++
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   569
  infixr 7 >>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   570
  infixr 6 ||
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   571
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   572
  val isAlphaNum =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   573
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   574
        val alphaNumChars = explode "_'"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   575
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   576
        fn c => mem c alphaNumChars orelse Char.isAlphaNum c
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   577
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   578
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   579
  local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   580
    val alphaNumToken = atLeastOne (some isAlphaNum) >> implode;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   581
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   582
    val symbolToken =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   583
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   584
          fun isNeg c = str c = !negation
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   585
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   586
          val symbolChars = explode "<>=-*+/\\?@|!$%&#^:;~"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   587
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   588
          fun isSymbol c = mem c symbolChars
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   589
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   590
          fun isNonNegSymbol c = not (isNeg c) andalso isSymbol c
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   591
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   592
          some isNeg >> str ||
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   593
          (some isNonNegSymbol ++ many (some isSymbol)) >> (implode o op::)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   594
        end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   595
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   596
    val punctToken =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   597
        let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   598
          val punctChars = explode "()[]{}.,"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   599
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   600
          fun isPunct c = mem c punctChars
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   601
        in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   602
          some isPunct >> str
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   603
        end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   604
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   605
    val lexToken = alphaNumToken || symbolToken || punctToken;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   606
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   607
    val space = many (some Char.isSpace);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   608
  in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   609
    val lexer = (space ++ lexToken ++ space) >> (fn (_,(tok,_)) => tok);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   610
  end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   611
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   612
  fun termParser inputStream =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   613
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   614
        val quants = !binders
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   615
        and iOps = !infixes
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   616
        and neg = !negation
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   617
        and bracks = ("(",")") :: !brackets
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   618
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   619
        val bracks = map (fn (b1,b2) => (b1 ^ b2, b1, b2)) bracks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   620
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   621
        val bTokens = map #2 bracks @ map #3 bracks
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   622
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   623
        fun possibleVarName "" = false
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   624
          | possibleVarName s = isAlphaNum (String.sub (s,0))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   625
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   626
        fun vName bv s = StringSet.member s bv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   627
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   628
        val iTokens = Print.tokensInfixes iOps
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   629
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   630
        val iParser =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   631
            parseInfixes iOps (fn (f,a,b) => Fn (Name.fromString f, [a,b]))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   632
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   633
        val specialTokens =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   634
            StringSet.addList iTokens (neg :: quants @ ["$"] @ bTokens)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   635
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   636
        fun varName bv =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   637
            some (vName bv) ||
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   638
            (some (Useful.equal "$") ++ some possibleVarName) >> snd
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   639
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   640
        fun fName bv s =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   641
            not (StringSet.member s specialTokens) andalso not (vName bv s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   642
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   643
        fun functionName bv =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   644
            some (fName bv) ||
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   645
            (some (Useful.equal "(") ++ any ++ some (Useful.equal ")")) >>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   646
            (fn (_,(s,_)) => s)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   647
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   648
        fun basic bv tokens =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   649
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   650
              val var = varName bv >> (Var o Name.fromString)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   651
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   652
              val const =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   653
                  functionName bv >> (fn f => Fn (Name.fromString f, []))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   654
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   655
              fun bracket (ab,a,b) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   656
                  (some (Useful.equal a) ++ term bv ++ some (Useful.equal b)) >>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   657
                  (fn (_,(tm,_)) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   658
                      if ab = "()" then tm else Fn (Name.fromString ab, [tm]))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   659
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   660
              fun quantifier q =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   661
                  let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   662
                    fun bind (v,t) =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   663
                        Fn (Name.fromString q, [Var (Name.fromString v), t])
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   664
                  in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   665
                    (some (Useful.equal q) ++
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   666
                     atLeastOne (some possibleVarName) ++
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   667
                     some (Useful.equal ".")) >>++
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   668
                    (fn (_,(vs,_)) =>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   669
                        term (StringSet.addList bv vs) >>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   670
                        (fn body => foldr bind body vs))
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   671
                  end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   672
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   673
              var ||
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   674
              const ||
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   675
              first (map bracket bracks) ||
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   676
              first (map quantifier quants)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   677
            end tokens
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   678
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   679
        and molecule bv tokens =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   680
            let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   681
              val negations = many (some (Useful.equal neg)) >> length
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   682
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   683
              val function =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   684
                  (functionName bv ++ many (basic bv)) >>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   685
                  (fn (f,args) => Fn (Name.fromString f, args)) ||
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   686
                  basic bv
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   687
            in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   688
              (negations ++ function) >>
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   689
              (fn (n,tm) => funpow n (fn t => Fn (Name.fromString neg, [t])) tm)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   690
            end tokens
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   691
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   692
        and term bv tokens = iParser (molecule bv) tokens
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   693
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   694
        term StringSet.empty
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   695
      end inputStream;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   696
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   697
  fun fromString input =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   698
      let
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   699
        val chars = Stream.fromList (explode input)
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   700
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   701
        val tokens = everything (lexer >> singleton) chars
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   702
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   703
        val terms = everything (termParser >> singleton) tokens
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   704
      in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   705
        case Stream.toList terms of
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   706
          [tm] => tm
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   707
        | _ => raise Error "Term.fromString"
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   708
      end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   709
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   710
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   711
local
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   712
  val antiquotedTermToString = Print.toString (Print.ppBracket "(" ")" pp);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   713
in
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   714
  val parse = Parse.parseQuotation antiquotedTermToString fromString;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   715
end;
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   716
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   717
end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   718
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   719
structure TermOrdered =
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   720
struct type t = Term.term val compare = Term.compare end
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   721
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   722
structure TermMap = KeyMap (TermOrdered);
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   723
6f9c9899f99f new version of the Metis files
blanchet
parents:
diff changeset
   724
structure TermSet = ElementSet (TermMap);