;;
-let print_subst subst =
- String.concat "\n"
+let print_subst ?(prefix="\n") subst =
+ String.concat prefix
(List.map
(fun (i, (c, t, ty)) ->
Printf.sprintf "?%d -> %s : %s" i
Printf.sprintf "[%d; %s]" cw s
-let weight_of_term term =
+let weight_of_term ?(consider_metas=true) term =
(* ALB: what to consider as a variable? I think "variables" in our case are
Metas and maybe Rels... *)
let module C = Cic in
let vars_dict = Hashtbl.create 5 in
let rec aux = function
- | C.Meta (metano, _) ->
+ | C.Meta (metano, _) when consider_metas ->
(try
let oldw = Hashtbl.find vars_dict metano in
Hashtbl.replace vars_dict metano (oldw+1)
with Not_found ->
Hashtbl.add vars_dict metano 1);
0
-
+ | C.Meta _ -> 0 (* "variables" are lighter than constants and functions...*)
+
| C.Var (_, ens)
| C.Const (_, ens)
| C.MutInd (_, _, ens)
| t1, t2 when t1 = t2 -> Eq
- | C.Rel n, C.Rel m -> if n > m then Lt else Gt (* ALB: changed < to > *)
+ | C.Rel n, C.Rel m -> if n > m then Lt else Gt
| C.Rel _, _ -> Lt
| _, C.Rel _ -> Gt
context
;;
+
+module OrderedTerm =
+struct
+ type t = Cic.term
+
+ let compare = Pervasives.compare
+end
+
+module TermSet = Set.Make(OrderedTerm);;
+module TermMap = Map.Make(OrderedTerm);;
+
+let symbols_of_term term =
+ let module C = Cic in
+ let rec aux map = function
+ | C.Meta _ -> map
+ | C.Appl l ->
+ List.fold_left (fun res t -> (aux res t)) map l
+ | t ->
+ let map =
+ try
+ let c = TermMap.find t map in
+ TermMap.add t (c+1) map
+ with Not_found ->
+ TermMap.add t 1 map
+ in
+ map
+ in
+ aux TermMap.empty term
+;;
+
+
+let metas_of_term term =
+ let module C = Cic in
+ let rec aux = function
+ | C.Meta _ as t -> TermSet.singleton t
+ | C.Appl l ->
+ List.fold_left (fun res t -> TermSet.union res (aux t)) TermSet.empty l
+ | t -> TermSet.empty (* TODO: maybe add other cases? *)
+ in
+ aux term
+;;
+
+
+let rec lpo t1 t2 =
+ let module C = Cic in
+ match t1, t2 with
+ | t1, t2 when t1 = t2 -> Eq
+ | t1, (C.Meta _ as m) ->
+ if TermSet.mem m (metas_of_term t1) then Gt else Incomparable
+ | (C.Meta _ as m), t2 ->
+ if TermSet.mem m (metas_of_term t2) then Lt else Incomparable
+ | C.Appl (hd1::tl1), C.Appl (hd2::tl2) -> (
+ let res =
+ let f o r t =
+ if r then true else
+ match lpo t o with
+ | Gt | Eq -> true
+ | _ -> false
+ in
+ let res1 = List.fold_left (f t2) false tl1 in
+ if res1 then Gt
+ else let res2 = List.fold_left (f t1) false tl2 in
+ if res2 then Lt
+ else Incomparable
+ in
+ if res <> Incomparable then
+ res
+ else
+ let f o r t =
+ if not r then false else
+ match lpo o t with
+ | Gt -> true
+ | _ -> false
+ in
+ match aux_ordering hd1 hd2 with
+ | Gt ->
+ let res = List.fold_left (f t1) false tl2 in
+ if res then Gt
+ else Incomparable
+ | Lt ->
+ let res = List.fold_left (f t2) false tl1 in
+ if res then Lt
+ else Incomparable
+ | Eq -> (
+ let lex_res =
+ try
+ List.fold_left2
+ (fun r t1 t2 -> if r <> Eq then r else lpo t1 t2)
+ Eq tl1 tl2
+ with Invalid_argument _ ->
+ Incomparable
+ in
+ match lex_res with
+ | Gt ->
+ if List.fold_left (f t1) false tl2 then Gt
+ else Incomparable
+ | Lt ->
+ if List.fold_left (f t2) false tl1 then Lt
+ else Incomparable
+ | _ -> Incomparable
+ )
+ | _ -> Incomparable
+ )
+ | t1, t2 -> aux_ordering t1 t2
+;;
+
+
+(* settable by the user... *)
+let compare_terms = ref nonrec_kbo;;
+
+
+type equality_sign = Negative | Positive;;
+
+let string_of_sign = function
+ | Negative -> "Negative"
+ | Positive -> "Positive"
+;;
+
+
+type pos = Left | Right
+
+let string_of_pos = function
+ | Left -> "Left"
+ | Right -> "Right"
+;;