wenzelm@29269: (* Title: Pure/term_ord.ML wenzelm@29269: Author: Tobias Nipkow and Makarius, TU Muenchen wenzelm@29269: wenzelm@29269: Term orderings. wenzelm@29269: *) wenzelm@29269: wenzelm@29269: signature TERM_ORD = wenzelm@29269: sig wenzelm@29269: val fast_indexname_ord: indexname * indexname -> order wenzelm@29269: val sort_ord: sort * sort -> order wenzelm@29269: val typ_ord: typ * typ -> order wenzelm@29269: val fast_term_ord: term * term -> order wenzelm@29269: val indexname_ord: indexname * indexname -> order wenzelm@29269: val tvar_ord: (indexname * sort) * (indexname * sort) -> order wenzelm@29269: val var_ord: (indexname * typ) * (indexname * typ) -> order wenzelm@29269: val term_ord: term * term -> order wenzelm@29269: val hd_ord: term * term -> order wenzelm@29269: val termless: term * term -> bool wenzelm@29269: val term_lpo: (term -> int) -> term * term -> order wenzelm@29269: end; wenzelm@29269: wenzelm@29269: structure TermOrd: TERM_ORD = wenzelm@29269: struct wenzelm@29269: wenzelm@29269: (* fast syntactic ordering -- tuned for inequalities *) wenzelm@29269: wenzelm@29269: fun fast_indexname_ord ((x, i), (y, j)) = wenzelm@29269: (case int_ord (i, j) of EQUAL => fast_string_ord (x, y) | ord => ord); wenzelm@29269: wenzelm@29269: fun sort_ord SS = wenzelm@29269: if pointer_eq SS then EQUAL wenzelm@29269: else dict_ord fast_string_ord SS; wenzelm@29269: wenzelm@29269: local wenzelm@29269: wenzelm@29269: fun cons_nr (TVar _) = 0 wenzelm@29269: | cons_nr (TFree _) = 1 wenzelm@29269: | cons_nr (Type _) = 2; wenzelm@29269: wenzelm@29269: in wenzelm@29269: wenzelm@29269: fun typ_ord TU = wenzelm@29269: if pointer_eq TU then EQUAL wenzelm@29269: else wenzelm@29269: (case TU of wenzelm@29269: (Type (a, Ts), Type (b, Us)) => wenzelm@29269: (case fast_string_ord (a, b) of EQUAL => dict_ord typ_ord (Ts, Us) | ord => ord) wenzelm@29269: | (TFree (a, S), TFree (b, S')) => wenzelm@29269: (case fast_string_ord (a, b) of EQUAL => sort_ord (S, S') | ord => ord) wenzelm@29269: | (TVar (xi, S), TVar (yj, S')) => wenzelm@29269: (case fast_indexname_ord (xi, yj) of EQUAL => sort_ord (S, S') | ord => ord) wenzelm@29269: | (T, U) => int_ord (cons_nr T, cons_nr U)); wenzelm@29269: wenzelm@29269: end; wenzelm@29269: wenzelm@29269: local wenzelm@29269: wenzelm@29269: fun cons_nr (Const _) = 0 wenzelm@29269: | cons_nr (Free _) = 1 wenzelm@29269: | cons_nr (Var _) = 2 wenzelm@29269: | cons_nr (Bound _) = 3 wenzelm@29269: | cons_nr (Abs _) = 4 wenzelm@29269: | cons_nr (_ $ _) = 5; wenzelm@29269: wenzelm@29269: fun struct_ord (Abs (_, _, t), Abs (_, _, u)) = struct_ord (t, u) wenzelm@29269: | struct_ord (t1 $ t2, u1 $ u2) = wenzelm@29269: (case struct_ord (t1, u1) of EQUAL => struct_ord (t2, u2) | ord => ord) wenzelm@29269: | struct_ord (t, u) = int_ord (cons_nr t, cons_nr u); wenzelm@29269: wenzelm@29269: fun atoms_ord (Abs (_, _, t), Abs (_, _, u)) = atoms_ord (t, u) wenzelm@29269: | atoms_ord (t1 $ t2, u1 $ u2) = wenzelm@29269: (case atoms_ord (t1, u1) of EQUAL => atoms_ord (t2, u2) | ord => ord) wenzelm@29269: | atoms_ord (Const (a, _), Const (b, _)) = fast_string_ord (a, b) wenzelm@29269: | atoms_ord (Free (x, _), Free (y, _)) = fast_string_ord (x, y) wenzelm@29269: | atoms_ord (Var (xi, _), Var (yj, _)) = fast_indexname_ord (xi, yj) wenzelm@29269: | atoms_ord (Bound i, Bound j) = int_ord (i, j) wenzelm@29269: | atoms_ord _ = sys_error "atoms_ord"; wenzelm@29269: wenzelm@29269: fun types_ord (Abs (_, T, t), Abs (_, U, u)) = wenzelm@29269: (case typ_ord (T, U) of EQUAL => types_ord (t, u) | ord => ord) wenzelm@29269: | types_ord (t1 $ t2, u1 $ u2) = wenzelm@29269: (case types_ord (t1, u1) of EQUAL => types_ord (t2, u2) | ord => ord) wenzelm@29269: | types_ord (Const (_, T), Const (_, U)) = typ_ord (T, U) wenzelm@29269: | types_ord (Free (_, T), Free (_, U)) = typ_ord (T, U) wenzelm@29269: | types_ord (Var (_, T), Var (_, U)) = typ_ord (T, U) wenzelm@29269: | types_ord (Bound _, Bound _) = EQUAL wenzelm@29269: | types_ord _ = sys_error "types_ord"; wenzelm@29269: wenzelm@29269: in wenzelm@29269: wenzelm@29269: fun fast_term_ord tu = wenzelm@29269: if pointer_eq tu then EQUAL wenzelm@29269: else wenzelm@29269: (case struct_ord tu of wenzelm@29269: EQUAL => (case atoms_ord tu of EQUAL => types_ord tu | ord => ord) wenzelm@29269: | ord => ord); wenzelm@29269: wenzelm@29269: end; wenzelm@29269: wenzelm@29269: wenzelm@29269: (* term_ord *) wenzelm@29269: wenzelm@29269: (*a linear well-founded AC-compatible ordering for terms: wenzelm@29269: s < t <=> 1. size(s) < size(t) or wenzelm@29269: 2. size(s) = size(t) and s=f(...) and t=g(...) and f string_ord (x, y) | ord => ord); wenzelm@29269: wenzelm@29269: val tvar_ord = prod_ord indexname_ord sort_ord; wenzelm@29269: val var_ord = prod_ord indexname_ord typ_ord; wenzelm@29269: wenzelm@29269: wenzelm@29269: local wenzelm@29269: wenzelm@29269: fun hd_depth (t $ _, n) = hd_depth (t, n + 1) wenzelm@29269: | hd_depth p = p; wenzelm@29269: wenzelm@29269: fun dest_hd (Const (a, T)) = (((a, 0), T), 0) wenzelm@29269: | dest_hd (Free (a, T)) = (((a, 0), T), 1) wenzelm@29269: | dest_hd (Var v) = (v, 2) wenzelm@29269: | dest_hd (Bound i) = ((("", i), dummyT), 3) wenzelm@29269: | dest_hd (Abs (_, T, _)) = ((("", 0), T), 4); wenzelm@29269: wenzelm@29269: in wenzelm@29269: wenzelm@29269: fun term_ord tu = wenzelm@29269: if pointer_eq tu then EQUAL wenzelm@29269: else wenzelm@29269: (case tu of wenzelm@29269: (Abs (_, T, t), Abs(_, U, u)) => wenzelm@29269: (case term_ord (t, u) of EQUAL => typ_ord (T, U) | ord => ord) wenzelm@29269: | (t, u) => wenzelm@29269: (case int_ord (size_of_term t, size_of_term u) of wenzelm@29269: EQUAL => wenzelm@29269: (case prod_ord hd_ord int_ord (hd_depth (t, 0), hd_depth (u, 0)) of wenzelm@29269: EQUAL => args_ord (t, u) | ord => ord) wenzelm@29269: | ord => ord)) wenzelm@29269: and hd_ord (f, g) = wenzelm@29269: prod_ord (prod_ord indexname_ord typ_ord) int_ord (dest_hd f, dest_hd g) wenzelm@29269: and args_ord (f $ t, g $ u) = wenzelm@29269: (case args_ord (f, g) of EQUAL => term_ord (t, u) | ord => ord) wenzelm@29269: | args_ord _ = EQUAL; wenzelm@29269: wenzelm@29269: fun termless tu = (term_ord tu = LESS); wenzelm@29269: wenzelm@29269: end; wenzelm@29269: wenzelm@29269: wenzelm@29269: (* Lexicographic path order on terms *) wenzelm@29269: wenzelm@29269: (* wenzelm@29269: See Baader & Nipkow, Term rewriting, CUP 1998. wenzelm@29269: Without variables. Const, Var, Bound, Free and Abs are treated all as wenzelm@29269: constants. wenzelm@29269: wenzelm@29269: f_ord maps terms to integers and serves two purposes: wenzelm@29269: - Predicate on constant symbols. Those that are not recognised by f_ord wenzelm@29269: must be mapped to ~1. wenzelm@29269: - Order on the recognised symbols. These must be mapped to distinct wenzelm@29269: integers >= 0. wenzelm@29269: The argument of f_ord is never an application. wenzelm@29269: *) wenzelm@29269: wenzelm@29269: local wenzelm@29269: wenzelm@29269: fun unrecognized (Const (a, T)) = ((1, ((a, 0), T)), 0) wenzelm@29269: | unrecognized (Free (a, T)) = ((1, ((a, 0), T)), 0) wenzelm@29269: | unrecognized (Var v) = ((1, v), 1) wenzelm@29269: | unrecognized (Bound i) = ((1, (("", i), dummyT)), 2) wenzelm@29269: | unrecognized (Abs (_, T, _)) = ((1, (("", 0), T)), 3); wenzelm@29269: wenzelm@29269: fun dest_hd f_ord t = wenzelm@29269: let val ord = f_ord t wenzelm@29269: in if ord = ~1 then unrecognized t else ((0, (("", ord), fastype_of t)), 0) end; wenzelm@29269: wenzelm@29269: fun term_lpo f_ord (s, t) = wenzelm@29269: let val (f, ss) = strip_comb s and (g, ts) = strip_comb t in wenzelm@29269: if forall (fn si => term_lpo f_ord (si, t) = LESS) ss wenzelm@29269: then case hd_ord f_ord (f, g) of wenzelm@29269: GREATER => wenzelm@29269: if forall (fn ti => term_lpo f_ord (s, ti) = GREATER) ts wenzelm@29269: then GREATER else LESS wenzelm@29269: | EQUAL => wenzelm@29269: if forall (fn ti => term_lpo f_ord (s, ti) = GREATER) ts wenzelm@29269: then list_ord (term_lpo f_ord) (ss, ts) wenzelm@29269: else LESS wenzelm@29269: | LESS => LESS wenzelm@29269: else GREATER wenzelm@29269: end wenzelm@29269: and hd_ord f_ord (f, g) = case (f, g) of wenzelm@29269: (Abs (_, T, t), Abs (_, U, u)) => wenzelm@29269: (case term_lpo f_ord (t, u) of EQUAL => typ_ord (T, U) | ord => ord) wenzelm@29269: | (_, _) => prod_ord (prod_ord int_ord wenzelm@29269: (prod_ord indexname_ord typ_ord)) int_ord wenzelm@29269: (dest_hd f_ord f, dest_hd f_ord g); wenzelm@29269: wenzelm@29269: in wenzelm@29269: val term_lpo = term_lpo wenzelm@29269: end; wenzelm@29269: wenzelm@29269: wenzelm@29269: end; wenzelm@29269: wenzelm@29269: structure Vartab = TableFun(type key = indexname val ord = TermOrd.fast_indexname_ord); wenzelm@29269: structure Typtab = TableFun(type key = typ val ord = TermOrd.typ_ord); wenzelm@29269: structure Termtab = TableFun(type key = term val ord = TermOrd.fast_term_ord);