src/HOL/Algebra/abstract/order.ML
changeset 13783 3294f727e20d
parent 13738 d48d1716bb6d
child 15531 08c8dad8e399
equal deleted inserted replaced
13782:44de406a7273 13783:3294f727e20d
     1 (*
     1 (*
     2   Title:     Term order, needed for normal forms in rings
     2   Title:     Term order, needed for normal forms in rings
     3   Id:        $Id$
     3   Id:        $Id$
     4   Author:    Clemens Ballarin and Roland Zumkeller
     4   Author:    Clemens Ballarin
     5   Copyright: TU Muenchen
     5   Copyright: TU Muenchen
     6 *)
     6 *)
     7 
     7 
     8 local
     8 local
     9 
     9 
    10 (* 
    10 (*** Lexicographic path order on terms.
    11 An order is a value of type
       
    12   ('a -> bool, 'a * 'a -> bool).
       
    13 
    11 
    14 The two parts are:
    12   See Baader & Nipkow, Term rewriting, CUP 1998.
    15  1) a unary predicate denoting the order's domain
    13   Without variables.  Const, Var, Bound, Free and Abs are treated all as
    16  2) a binary predicate with the semanitcs "greater than"
    14   constants.
    17 
    15 
    18 If (d, ord) is an order then ord (a,b) is defined if both d a and d b.
    16   f_ord maps strings to integers and serves two purposes:
    19 *)
    17   - Predicate on constant symbols.  Those that are not recognised by f_ord
       
    18     must be mapped to ~1.
       
    19   - Order on the recognised symbols.  These must be mapped to distinct
       
    20     integers >= 0.
    20 
    21 
    21 (*
    22 ***)
    22 Combines two orders with disjoint domains and returns
       
    23 another one. 
       
    24 When the compared values are from the same domain, the corresponding
       
    25 order is used. If not the ones from the first domain are considerer
       
    26 greater. (If a value is in neither of the two domains, exception
       
    27 "Domain" is raised.)
       
    28 *)
       
    29 
    23 
    30 fun combineOrd ((d1, ord1), (d2, ord2)) = 
    24 fun dest_hd f_ord (Const (a, T)) = 
    31   (fn x => d1 x orelse d2 x, 
    25       let val ord = f_ord a in
    32    fn (a, b) =>
    26         if ord = ~1 then ((1, ((a, 0), T)), 0) else ((0, (("", ord), T)), 0)
    33      if d1 a andalso d1 b then ord1 (a, b) else
    27       end
    34      if d1 a andalso d2 b then true else
    28   | dest_hd _ (Free (a, T)) = ((1, ((a, 0), T)), 0)
    35      if d2 a andalso d2 b then ord2 (a, b) else
    29   | dest_hd _ (Var v) = ((1, v), 1)
    36      if d2 a andalso d1 b then false else raise Domain)
    30   | dest_hd _ (Bound i) = ((1, (("", i), Term.dummyT)), 2)
       
    31   | dest_hd _ (Abs (_, T, _)) = ((1, (("", 0), T)), 3);
    37 
    32 
    38 
    33 fun term_lpo f_ord (s, t) =
    39 (* Counts the number of function applications + 1. *)
    34   let val (f, ss) = strip_comb s and (g, ts) = strip_comb t in
    40 (* ### is there a standard Isabelle function for this? *)
    35     if forall (fn si => term_lpo f_ord (si, t) = LESS) ss
    41 
    36     then case hd_ord f_ord (f, g) of
    42 fun tsize (a $ b) = tsize a + tsize b
    37 	GREATER =>
    43   | tsize _ = 1;
    38 	  if forall (fn ti => term_lpo f_ord (s, ti) = GREATER) ts
    44 
    39 	  then GREATER else LESS
    45 (* foldl on non-empty lists *)
    40       | EQUAL =>
    46 
    41 	  if forall (fn ti => term_lpo f_ord (s, ti) = GREATER) ts
    47 fun foldl2 f (x::xs) = foldl f (x,xs)
    42 	  then list_ord (term_lpo f_ord) (ss, ts)
    48 
    43 	  else LESS
    49 
    44       | LESS => LESS
    50 (* Compares two terms, ignoring type information. *)
    45     else GREATER
    51 infix e;
    46   end
    52 fun (Const (s1, _))   e (Const (s2, _))   = s1 = s2
    47 and hd_ord f_ord (f, g) = case (f, g) of
    53   | (Free (s1, _))    e (Free (s2, _))    = s1 = s2
    48     (Abs (_, T, t), Abs (_, U, u)) =>
    54   | (Var (ix1, _))    e (Var (ix2, _))    = ix1 = ix2
    49       (case term_lpo f_ord (t, u) of EQUAL => Term.typ_ord (T, U) | ord => ord)
    55   | (Bound i1)        e (Bound i2)        = i1 = i2
    50   | (_, _) => prod_ord (prod_ord int_ord
    56   | (Abs (s1, _, t1)) e (Abs (s2, _, t2)) = s1 = s2 andalso t1 = t2
    51                   (prod_ord Term.indexname_ord Term.typ_ord)) int_ord
    57   | (s1 $ s2)         e (t1 $ t2)         = s1 = t1 andalso s2 = t2
    52                 (dest_hd f_ord f, dest_hd f_ord g)
    58   | _ e _ = false
       
    59 
       
    60 
       
    61 
       
    62 (* Curried lexicographich path order induced by an order on function symbols.
       
    63 Its feature include:
       
    64 - compatibility with Epsilon-operations 
       
    65 - closure under substitutions
       
    66 - well-foundedness
       
    67 - subterm-property
       
    68 - termination
       
    69 - defined on all terms (not only on ground terms)
       
    70 - linearity
       
    71 
       
    72 The order ignores types.
       
    73 *)
       
    74 
       
    75 infix g;
       
    76 fun clpo (d, ord) (s,t) = 
       
    77   let val (op g) = clpo (d, ord) in
       
    78      (s <> t) andalso
       
    79      if tsize s < tsize t then not (t g s) else
       
    80        (* improves performance. allowed because clpo is total. *)
       
    81      #2 (foldl2 combineOrd [
       
    82         (fn _ $ _ => true | Abs _ => true | _ => false, 
       
    83   	 fn (Abs (_, _, s'), t) => s' e t orelse s' g t orelse 
       
    84  				   (case t of
       
    85  					Abs (_, _, t') => s' g t'
       
    86  				      | t1 $ t2 => s g t1 andalso s g t2
       
    87  			           )
       
    88            | (s1 $ s2, t) => s1 e t orelse s2 e t orelse 
       
    89                              s1 g t orelse s2 g t orelse
       
    90  			    (case t of
       
    91  				 t1 $ t2 => (s1 e t1 andalso s2 g t2) orelse
       
    92  					    (s1 g t1 andalso s g t2)
       
    93  			       | _ => false
       
    94                              )
       
    95         ),
       
    96         (fn Free _       => true      | _ => false,   fn (Free (a,_), Free (b,_))     => a > b),
       
    97         (fn Bound _      => true      | _ => false,   fn (Bound a, Bound b)           => a > b),
       
    98         (fn Const (c, _) => not (d c) | _ => false,   fn (Const (a, _), Const (b, _)) => a > b),
       
    99         (fn Const (c, _) => d c       | _ => false,   fn (Const (a, _), Const (b, _)) => ord (a,b))
       
   100     ]) (s,t)
       
   101   end;
       
   102 
       
   103 (*
       
   104 Open Issues: 
       
   105 - scheme variables have to be ordered (should be simple)
       
   106 *)
       
   107 
       
   108 (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *)
       
   109 
       
   110 (* Returns the position of an element in a list. If the
       
   111 element doesn't occur in the list, a MatchException is raised. *)
       
   112 fun pos (x::xs) i = if x = i then 0 else 1 + pos xs i;
       
   113 
       
   114 (* Generates a finite linear order from a list. 
       
   115 [a, b, c] results in the order "a > b > c". *)
       
   116 fun linOrd l = fn (a,b) => pos l a < pos l b;
       
   117 
       
   118 (* Determines whether an element is contained in a list. *)
       
   119 fun contains (x::xs) i = (x = i) orelse (contains xs i) |
       
   120     contains [] i = false;
       
   121 
    53 
   122 in
    54 in
   123 
    55 
   124 (* Term order for commutative rings *)
    56 (*** Term order for commutative rings ***)
   125 
    57 
   126 fun termless_ring (a, b) =
    58 fun ring_ord a =
   127   let
    59   find_index_eq a ["0", "op +", "uminus", "op -", "1", "op *"];
   128     val S = ["op *", "op -", "uminus", "op +", "0"];
    60 
   129     (* Order (decending from left to right) on the constant symbols *)
    61 fun termless_ring (a, b) = (term_lpo ring_ord (a, b) = LESS);
   130     val baseOrd = (contains S, linOrd S);
    62 
   131   in clpo baseOrd (b, a)
    63 (* Some code useful for debugging
   132   end;
    64 
       
    65 val intT = HOLogic.intT;
       
    66 val a = Free ("a", intT);
       
    67 val b = Free ("b", intT);
       
    68 val c = Free ("c", intT);
       
    69 val plus = Const ("op +", [intT, intT]--->intT);
       
    70 val mult = Const ("op *", [intT, intT]--->intT);
       
    71 val uminus = Const ("uminus", intT-->intT);
       
    72 val one = Const ("1", intT);
       
    73 val f = Const("f", intT-->intT);
       
    74 
       
    75 *)
   133 
    76 
   134 (*** Rewrite rules ***)
    77 (*** Rewrite rules ***)
   135 
    78 
   136 val a_assoc = thm "ring.a_assoc";
    79 val a_assoc = thm "ring.a_assoc";
   137 val l_zero = thm "ring.l_zero";
    80 val l_zero = thm "ring.l_zero";
   231      simp_tac (simpset() addsimps [r_null, r_neg]) 1]);
   174      simp_tac (simpset() addsimps [r_null, r_neg]) 1]);
   232 
   175 
   233 val ring_ss = HOL_basic_ss settermless termless_ring addsimps
   176 val ring_ss = HOL_basic_ss settermless termless_ring addsimps
   234   [a_assoc, l_zero, l_neg, a_comm, m_assoc, l_one, l_distr, m_comm, minus_def,
   177   [a_assoc, l_zero, l_neg, a_comm, m_assoc, l_one, l_distr, m_comm, minus_def,
   235    r_zero, r_neg, r_neg2, r_neg1, minus_add, minus_minus, minus0,
   178    r_zero, r_neg, r_neg2, r_neg1, minus_add, minus_minus, minus0,
   236    a_lcomm, m_lcomm, r_distr, l_null, r_null, l_minus, r_minus];
   179    a_lcomm, m_lcomm, (*r_one,*) r_distr, l_null, r_null, l_minus, r_minus];
   237 
   180 
   238 val x = bind_thms ("ring_simps", [l_zero, r_zero, l_neg, r_neg,
   181 (* Note: r_one is not necessary in ring_ss *)
   239   minus_minus, minus0, 
   182 
       
   183 val x = bind_thms ("ring_simps", 
       
   184   [l_zero, r_zero, l_neg, r_neg, minus_minus, minus0, 
   240   l_one, r_one, l_null, r_null, l_minus, r_minus]);
   185   l_one, r_one, l_null, r_null, l_minus, r_minus]);
   241 
       
   242 (* note: r_one added to ring_simp but not ring_ss *)
       
   243 
   186 
   244 (* note: not added (and not proved):
   187 (* note: not added (and not proved):
   245   a_lcancel_eq, a_rcancel_eq, power_one, power_Suc, power_zero, power_one,
   188   a_lcancel_eq, a_rcancel_eq, power_one, power_Suc, power_zero, power_one,
   246   m_lcancel_eq, m_rcancel_eq,
   189   m_lcancel_eq, m_rcancel_eq,
   247   thms involving dvd, integral domains, fields
   190   thms involving dvd, integral domains, fields