home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / progrmng / cmlmcmpw.sit / Caml Light / examples / kb / kb.ml < prev    next >
Encoding:
Text File  |  1991-05-23  |  5.0 KB  |  148 lines  |  [TEXT/MPS ]

  1. #open "prelude";;
  2. #open "terms";;
  3. #open "equation";;
  4.  
  5. (****************** Critical pairs *********************)
  6.  
  7. (* All (u,sig) such that N/u (&var) unifies with M,
  8.    with principal unifier sig *)
  9. (* super : term -> term -> (num list & subst) list *)
  10. let super M = suprec where rec suprec = function
  11.     Term(_,sons) as N ->
  12.       let collate (pairs,n) son =
  13.        (pairs @ map (fun (u,sig) -> (n::u,sig)) (suprec son), n+1) in
  14.       let insides = fst (it_list collate ([],1) sons) in
  15.        (try
  16.           ([], unify(M,N)) :: insides
  17.         with failure _ -> insides)
  18.   | _ -> []
  19. ;;
  20.  
  21. (* Ex :
  22. let (M,_) = <<F(A,B)>> 
  23. and (N,_) = <<H(F(A,x),F(x,y))>> in super M N;;
  24. ==> [[1],[2,Term ("B",[])];                      x <- B
  25.      [2],[2,Term ("A",[]); 1,Term ("B",[])]]     x <- A  y <- B
  26. *)
  27.  
  28. (* All (u,sig), u&[], such that N/u unifies with M *)
  29. (* super_strict : term -> term -> (num list & subst) list *)
  30. let super_strict M = function
  31.       Term(_,sons) ->
  32.         let collate (pairs,n) son =
  33.           (pairs @ map (fun (u,sig) -> (n::u,sig)) (super M son), n+1) in
  34.         fst (it_list collate ([],1) sons)
  35.     | _ -> []
  36. ;;
  37.  
  38. (* Critical pairs of L1=R1 with L2=R2 *)
  39. (* critical_pairs : term_pair -> term_pair -> term_pair list *)
  40. let critical_pairs (L1,R1) (L2,R2) =
  41.   let mk_pair (u,sig) =
  42.      substitute sig (replace L2 u R1), substitute sig R2 in
  43.   map mk_pair (super L1 L2);;
  44.  
  45. (* Strict critical pairs of L1=R1 with L2=R2 *)
  46. (* strict_critical_pairs : term_pair -> term_pair -> term_pair list *)
  47. let strict_critical_pairs (L1,R1) (L2,R2) =
  48.   let mk_pair (u,sig) =
  49.     substitute sig (replace L2 u R1), substitute sig R2 in
  50.   map mk_pair (super_strict L1 L2)
  51. ;;
  52.  
  53. (* All critical pairs of eq1 with eq2 *)
  54. let mutual_critical_pairs eq1 eq2 =
  55.   (strict_critical_pairs eq1 eq2) @ (critical_pairs eq2 eq1);;
  56.  
  57. (* Renaming of variables *)
  58.  
  59. let rename n (t1,t2) =
  60.   let rec ren_rec = function
  61.     Var k -> Var(k+n)
  62.   | Term(op,sons) -> Term(op, map ren_rec sons) in
  63.   (ren_rec t1, ren_rec t2)
  64. ;;
  65.  
  66. (************************ Completion ******************************)
  67.  
  68. let deletion_message (k,_) =
  69.   print_string "Rule ";print_int k; message " deleted"
  70. ;;
  71.  
  72. (* Generate failure message *)
  73. let non_orientable (M,N) =
  74.     pretty_term M; print_string " = "; pretty_term N; print_newline()
  75. ;;
  76.  
  77. (* Improved Knuth-Bendix completion procedure *)
  78. (* kb_completion : (term_pair -> bool) -> num -> rules -> term_pair list ->
  79.      (num & num) -> term_pair list -> rules *)
  80. let kb_completion greater = kbrec where rec kbrec n rules =
  81.   let normal_form = mrewrite_all rules
  82.   and get_rule k = assoc k rules in process
  83.   where rec process failures = processf
  84.   where rec processf (k,l) =
  85.    (processkl where rec processkl eqs =
  86. (***
  87.      print_string "***kb_completion "; print_int n; print_newline();
  88.      pretty_rules rules;
  89.      do_list non_orientable failures;
  90.      print_int k; print_string " "; print_int l; print_newline();
  91.      do_list non_orientable eqs;
  92. ***)
  93.      match eqs with
  94.      [] ->
  95.       if k<l then next_criticals (k+1,l) else
  96.       if l<n then next_criticals (1,l+1) else
  97.        (match failures with
  98.           [] -> rules (* successful completion *)
  99.         | _  -> message "Non-orientable equations :";
  100.                 do_list non_orientable failures;
  101.                 failwith "kb_completion")
  102.    | (M,N)::eqs ->
  103.       let M' = normal_form M
  104.       and N' = normal_form N
  105.       and enter_rule(left,right) =
  106.         let new_rule = (n+1, mk_rule left right) in
  107.           pretty_rule new_rule;
  108.           let left_reducible (_,(_,(L,_))) = reducible left L in
  109.           let redl,irredl = partition left_reducible rules in
  110.             do_list deletion_message redl;
  111.             let irreds = (map right_reduce irredl
  112.                  where right_reduce (m,(_,(L,R))) = 
  113.                        m,mk_rule L (mrewrite_all (new_rule::rules) R))
  114.             and eqs' = map (fun (_,(_,pair)) -> pair) redl in
  115.              kbrec (n+1) (new_rule::irreds) [] (k,l) (eqs @ eqs' @ failures) in
  116.       if M'=N' then processkl eqs else
  117.       if greater(M',N') then enter_rule(M',N') else
  118.       if greater(N',M') then enter_rule(N',M') else
  119.         process ((M',N')::failures) (k,l) eqs)
  120.   and next_criticals (k,l) =
  121. (***
  122.     print_string "***next_criticals ";
  123.     print_int k; print_string " "; print_int l ; print_newline();
  124. ***)
  125.     try
  126.       let (v,el) = get_rule l in
  127.         if k=l then
  128.           processf (k,l) (strict_critical_pairs el (rename v el))
  129.         else
  130.           try
  131.             let (_,ek) = get_rule k in 
  132.               processf (k,l) (mutual_critical_pairs el (rename v ek))
  133.       with failure "find" (*rule k deleted*) -> next_criticals (k+1,l)
  134.     with failure "find" (*rule l deleted*) -> next_criticals (1,l+1)
  135. ;;
  136.  
  137. (* complete_rules is assumed locally confluent, and checked Noetherian with
  138.   ordering greater, rules is any list of rules *)
  139.  
  140. let kb_complete greater complete_rules rules =
  141.     let n = check_rules complete_rules
  142.     and eqs = map (fun (_,(_,pair)) -> pair) rules in
  143.     let completed_rules =
  144.       kb_completion greater n complete_rules [] (n,n) eqs in
  145.     message "Canonical set found :";
  146.     pretty_rules (rev completed_rules);()
  147. ;;
  148.