Advertisement
Guest User

Untitled

a guest
Mar 26th, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.71 KB | None | 0 0
  1. let rec find quot node =
  2. if quot.(node) = node
  3. then node
  4. else
  5. let repr = find quot quot.(node) in
  6. quot.(node) <- repr;
  7. repr
  8.  
  9. let union quot node1 node2 =
  10. let repr1 = find quot node1
  11. and repr2 = find quot node2 in
  12. quot.(repr2) <- repr1
  13.  
  14. let equiv quot node1 node2 =
  15. find quot node1 = find quot node2
  16.  
  17. type termgraph =
  18. {
  19. id : int;
  20. label : int;
  21. children : termgraph list;
  22. }
  23.  
  24. let congruent quot p q =
  25. p.label = q.label && List.for_all2 (fun pi qi -> equiv quot pi.id qi.id ) p.children q.children
  26.  
  27. let rec preds quot i t =
  28. if List.exists (fun ti -> equiv quot i ti.id) t.children
  29. then t :: List.concat (List.map (preds quot i) t.children)
  30. else List.concat (List.map (preds quot i) t.children)
  31.  
  32. let rec merge quot t i j =
  33. if equiv quot i j
  34. then ()
  35. else
  36. let u = preds quot i t
  37. and v = preds quot j t in
  38. union quot i j;
  39. List.iter (fun ui ->
  40. List.iter (fun vi ->
  41. if equiv quot ui.id vi.id || not (congruent quot ui vi)
  42. then ()
  43. else merge quot t ui.id vi.id) v) u
  44.  
  45. type term = Term of int * term list
  46.  
  47. let rec from_term' m (Term (n, ts)) =
  48. let children, m' = from_term'' (m+1) ts in
  49. { id = m; label = n; children = children; }, m'
  50. and from_term'' m = function
  51. | [] -> [], m
  52. | t::ts ->
  53. let graph, m' = from_term' m t in
  54. let ts', m'' = from_term'' m' ts in
  55. (graph :: ts', m'')
  56.  
  57. let from_term t = from_term' 0 t
  58.  
  59. let tinit ts = List.fold_right (fun (t1, t2) xs -> t1 :: t2 :: xs) ts []
  60.  
  61. let rec drop n = function
  62. | [] -> []
  63. | x :: xs -> if n = 0 then x :: xs else drop (n-1) xs
  64.  
  65. let rec cc' quot t rules =
  66. List.iter (fun (p, q) -> merge quot t p q) rules;
  67. quot, t
  68.  
  69. let rec subterm t (Term (n, ts)) =
  70. if t = Term (n, ts)
  71. then true
  72. else List.exists (subterm t) ts
  73.  
  74. let rec leaves graph =
  75. match graph.children with
  76. | [] -> [graph]
  77. | _ -> List.concat (List.map leaves graph.children)
  78.  
  79. let rec somes f = function
  80. | [] -> []
  81. | x :: xs ->
  82. match f x with
  83. | Some y -> y :: somes f xs
  84. | None -> somes f xs
  85.  
  86. let rec leaves_congr' base = function
  87. | [] -> []
  88. | c :: cs ->
  89. if List.mem c.label base
  90. then leaves_congr' base cs
  91. else
  92. let cs' = somes (fun c' -> if c.label = c'.label then Some c' else None) cs in
  93. List.map (fun c' -> (c.id, c'.id)) cs' @ leaves_congr' (c.label :: base) cs
  94.  
  95. let leaves_congr graph = leaves_congr' [] (leaves graph)
  96.  
  97. let rec tuples = function
  98. | [] -> []
  99. | _ :: [] -> []
  100. | x :: y :: xs -> (x, y) :: tuples xs
  101.  
  102. let cc symb l r rules =
  103. let t, m = from_term (Term (symb, tinit ((l, r) :: rules))) in
  104. let quot = Array.init m (fun x -> x) in
  105. let rules_id = leaves_congr t @ tuples (drop 2 (List.map (fun x -> x.id) t.children)) in
  106. cc' quot t rules_id
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement