Changed term ordering for permutative rewrites to be AC-compatible.
authornipkow
Sun, 27 Mar 1994 12:33:14 +0200
changeset 3054c2bbb5de471
parent 304 5edc4f5e5ebd
child 306 eee166d4a532
Changed term ordering for permutative rewrites to be AC-compatible.
src/Pure/thm.ML
     1.1 --- a/src/Pure/thm.ML	Thu Mar 24 18:14:45 1994 +0100
     1.2 +++ b/src/Pure/thm.ML	Sun Mar 27 12:33:14 1994 +0200
     1.3 @@ -991,51 +991,47 @@
     1.4  type termrec = (Sign.sg * term list) * term;
     1.5  type conv = meta_simpset -> termrec -> termrec;
     1.6  
     1.7 -datatype comparison = LESS | EQUAL | GREATER;
     1.8 +datatype order = LESS | EQUAL | GREATER;
     1.9  
    1.10 -fun stringcomp(a,b:string) = if a<b then LESS  else
    1.11 -                             if a=b then EQUAL else GREATER;
    1.12 +fun stringord(a,b:string) = if a<b then LESS  else
    1.13 +                            if a=b then EQUAL else GREATER;
    1.14  
    1.15 -fun intcomp(i,j:int) = if i<j then LESS  else
    1.16 -                       if i=j then EQUAL else GREATER;
    1.17 +fun intord(i,j:int) = if i<j then LESS  else
    1.18 +                      if i=j then EQUAL else GREATER;
    1.19  
    1.20 -fun xcomp((a,i),(b,j)) =
    1.21 -  (case stringcomp(a,b) of EQUAL => intcomp(i,j) | c => c);
    1.22 +(* FIXME: "***ABSTRACTION***" is a hack and makes the ordering non-linear *)
    1.23 +fun string_of_hd(Const(a,_)) = a
    1.24 +  | string_of_hd(Free(a,_))  = a
    1.25 +  | string_of_hd(Var(v,_))   = Syntax.string_of_vname v
    1.26 +  | string_of_hd(Bound i)    = string_of_int i
    1.27 +  | string_of_hd(Abs _)      = "***ABSTRACTION***";
    1.28  
    1.29 -(*a strict (not reflexive) linear ordering for terms*)
    1.30 +(* a strict (not reflexive) linear well-founded AC-compatible ordering
    1.31 + * for terms:
    1.32 + * s < t <=> 1. size(s) < size(t) or
    1.33 +             2. size(s) = size(t) and s=f(...) and t = g(...) and f<g or
    1.34 +             3. size(s) = size(t) and s=f(s1..sn) and t=f(t1..tn) and
    1.35 +                (s1..sn) < (t1..tn) (lexicographically)
    1.36 + *)
    1.37 +
    1.38  (* FIXME: should really take types into account as well.
    1.39 -   Otherwise not linear *)
    1.40 -fun termcomp (t,u) =
    1.41 -  (case t of
    1.42 -     Const(a,_) => (case u of
    1.43 -                      Const(b,_) => stringcomp(a,b)
    1.44 -                    | _          => GREATER)
    1.45 -   | Free(a,_) => (case u of
    1.46 -                     Const _   => LESS
    1.47 -                   | Free(b,_) => stringcomp(a,b)
    1.48 -                   | _         => GREATER)
    1.49 -   | Var(v,_) => (case u of
    1.50 -                    Const _  => LESS
    1.51 -                  | Free _   => LESS
    1.52 -                  | Var(w,_) => xcomp(v,w)
    1.53 -                  | _        => GREATER)
    1.54 -  | Bound i => (case u of
    1.55 -                  Const _  => LESS
    1.56 -                | Free _   => LESS
    1.57 -                | Var _    => LESS
    1.58 -                | Bound j  => intcomp(i,j)
    1.59 -                | _        => GREATER)
    1.60 -  | Abs(_,_,r) => (case u of
    1.61 -                     _ $ _  => GREATER
    1.62 -                   | Abs(_,_,s) => termcomp(r,s)
    1.63 -                   | _          => LESS)
    1.64 -  | t1$t2 => (case u of
    1.65 -                u1$u2 => (case termcomp(t1,u1) of
    1.66 -                            EQUAL => termcomp(t2,u2)
    1.67 -                          | c => c)
    1.68 -              |  _    => LESS));
    1.69 + * Otherwise not linear *)
    1.70 +fun termord(t,u) =
    1.71 +      (case intord(size_of_term t,size_of_term u) of
    1.72 +         EQUAL => let val (f,ts) = strip_comb t and (g,us) = strip_comb u
    1.73 +                  in case stringord(string_of_hd f, string_of_hd g) of
    1.74 +                       EQUAL => lextermord(ts,us)
    1.75 +                     | ord   => ord
    1.76 +                  end
    1.77 +       | ord => ord)
    1.78 +and lextermord(t::ts,u::us) =
    1.79 +      (case termord(t,u) of
    1.80 +         EQUAL => lextermord(ts,us)
    1.81 +       | ord   => ord)
    1.82 +  | lextermord([],[]) = EQUAL
    1.83 +  | lextermord _ = error("lextermord");
    1.84  
    1.85 -fun termless tu = (termcomp tu = LESS);
    1.86 +fun termless tu = (termord tu = LESS);
    1.87  
    1.88  fun check_conv(thm as Thm{hyps,prop,...}, prop0) =
    1.89    let fun err() = (trace_thm "Proved wrong thm (Check subgoaler?)" thm; None)