main.rs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. use std::rc::Rc;
  2. // type id = string
  3. #[derive(Eq, PartialEq, Clone, Debug)]
  4. struct Id(Rc<String>);
  5. //type term =
  6. //| Var of id
  7. //| Term of id * term list
  8. #[derive(Eq, PartialEq, Clone, Debug)]
  9. enum Term {
  10. Var(Id),
  11. Ter(Id, Vec<Term>),
  12. }
  13. //(* invariant for substitutions: *)
  14. //(* no id on a lhs occurs in any term earlier in the list *)
  15. //type substitution = (id * term) list
  16. #[derive(Eq, PartialEq, Clone, Debug)]
  17. struct Substitution(Vec<(Id, Term)>);
  18. /*
  19. (* check if a variable occurs in a term *)
  20. let rec occurs (x : id) (t : term) : bool =
  21. match t with
  22. | Var y -> x = y
  23. | Term (_, s) -> List.exists (occurs x) s
  24. */
  25. fn occurs(x: &Id, t: &Term) -> bool {
  26. match t {
  27. Term::Var(id) => id == x,
  28. Term::Ter(_, s) => s.iter().find(|t| occurs(x, t)).is_some()
  29. }
  30. }
  31. /*
  32. (* substitute term s for all occurrences of variable x in term t *)
  33. let rec subst (s : term) (x : id) (t : term) : term =
  34. match t with
  35. | Var y -> if x = y then s else t
  36. | Term (f, u) -> Term (f, List.map (subst s x) u)
  37. */
  38. fn subst(s: &Term, x: &Id, t: &Term) -> Term {
  39. match t {
  40. Term::Var(y) => if x == y { s.clone() } else { Term::Var(y.clone()) },
  41. Term::Ter(f, u) => Term::Ter(f.clone(),
  42. u.iter().map(|q| subst(s, x, q)).collect())
  43. }
  44. }
  45. /*
  46. (* apply a substitution right to left *)
  47. let apply (s : substitution) (t : term) : term =
  48. List.fold_right (fun (x, u) -> subst u x) s t
  49. */
  50. fn apply(Substitution(s): &Substitution, t: &Term) -> Term {
  51. s.iter().fold(t.clone(), |q, (x, u)| subst(u, x, &q))
  52. }
  53. /*
  54. (* unify one pair *)
  55. let rec unify_one (s : term) (t : term) : substitution =
  56. match (s, t) with
  57. | (Var x, Var y) -> if x = y then [] else [(x, t)]
  58. | (Term (f, sc), Term (g, tc)) ->
  59. if f = g && List.length sc = List.length tc
  60. then unify (List.combine sc tc)
  61. else failwith "not unifiable: head symbol conflict"
  62. | ((Var x, (Term (_, _) as t)) | ((Term (_, _) as t), Var x)) ->
  63. if occurs x t
  64. then failwith "not unifiable: circularity"
  65. else [(x, t)]
  66. */
  67. fn unify_one(s: &Term, t: &Term) -> Result<Substitution, &'static str> {
  68. match (s, t) {
  69. (Term::Var(x), Term::Var(y)) =>
  70. Ok(Substitution(if x == y { Vec::new() } else { vec![(x.clone(), t.clone())] })),
  71. (Term::Ter(f, sc), Term::Ter(g, tc)) =>
  72. if f == g && sc.len() == tc.len()
  73. { unify(sc.iter().zip(tc.iter()).collect()) } else { Err("Cannot into: head symbol conflict") },
  74. (Term::Var(x), t @ Term::Ter(_, _)) | (t @ Term::Ter(_, _), Term::Var(x)) =>
  75. if occurs(x, t) { Err("koło") } else { Ok(Substitution(vec![(x.clone(), t.clone())])) }
  76. }
  77. }
  78. /*
  79. (* unify a list of pairs *)
  80. and unify (s : (term * term) list) : substitution =
  81. match s with
  82. | [] -> []
  83. | (x, y) :: t ->
  84. let t2 = unify t in
  85. let t1 = unify_one (apply t2 x) (apply t2 y) in
  86. t1 @ t2
  87. */
  88. fn unify(s: Vec<(&Term, &Term)>) -> Result<Substitution, &'static str> {
  89. match s.split_first() {
  90. None => Ok(Substitution(Vec::new())), // Vec::new nie grabi pamięci \:D/
  91. Some(((x, y), t)) => {
  92. let t = unify(t.to_vec())?;
  93. let Substitution(t1) =
  94. unify_one(&apply(&t, &x), &apply(&t, &y))?;
  95. let Substitution(v) = t;
  96. // mógłbym rozszerzać t1 (t1.extend(v);), ale tak bezpieczniej
  97. Ok(Substitution(t1.into_iter().chain(v.into_iter()).collect()))
  98. }
  99. }
  100. }
  101. fn main() {
  102. {
  103. let mut x = "x".to_owned();
  104. let a1 = Rc::new("xd".to_owned());
  105. x.push('d');
  106. let a2 = Rc::new(x);
  107. println!("{}, {}", a1 == a2, &a1 == &a2);
  108. let a3 = a2.clone();
  109. println!(" {} {}", Rc::strong_count(&a2), Rc::strong_count(&a3), )
  110. }
  111. let a1 = Term::Var(Id(Rc::new("xd".to_owned())));
  112. let a2 = Term::Var(Id(Rc::new("qw".to_owned())));
  113. println!("{:?} -- {:?} ---> {:?}", &a1, &a2, unify_one(&a1, &a2));
  114. let a1 = Term::Ter(Id(Rc::new("xdaad".to_owned())), vec![]);
  115. let a2 = Term::Ter(Id(Rc::new("xdaad".to_owned())), vec![]);
  116. println!("{:?} -- {:?} ---> {:?}", &a1, &a2, unify_one(&a1, &a2));
  117. let a1 = Term::Ter(Id(Rc::new("int".to_owned())), vec![]);
  118. let a2 = Term::Ter(Id(Rc::new("nat".to_owned())), vec![]);
  119. println!("{:?} -- {:?} ---> {:?}", &a1, &a2, unify_one(&a1, &a2));
  120. let a1 = Term::Ter(Id(Rc::new("xdaad".to_owned())), vec![Term::Var(Id(Rc::new("fffxd".to_owned())))]);
  121. let a2 = Term::Ter(Id(Rc::new("xdaad".to_owned())), vec![Term::Var(Id(Rc::new("zxczxc".to_owned())))]);
  122. println!("{:?} -- {:?} ---> {:?}", &a1, &a2, unify_one(&a1, &a2));
  123. let a1 = Term::Ter(Id(Rc::new("xdaad".to_owned())), vec![Term::Var(Id(Rc::new("fffxd".to_owned())))]);
  124. let a2 = Term::Ter(Id(Rc::new("xdfewfewfewefaad".to_owned())), vec![Term::Var(Id(Rc::new("zxczxc".to_owned())))]);
  125. println!("{:?} -- {:?} ---> {:?}", &a1, &a2, unify_one(&a1, &a2));
  126. let a1 = Term::Ter(Id(Rc::new("int".to_owned())), Vec::new());
  127. let a2 = Term::Var(Id(Rc::new("xdaad".to_owned())));
  128. println!("{:?} -- {:?} ---> {:?}", &a1, &a2, unify_one(&a1, &a2));
  129. println!("{:?} -- {:?} ---> {:?}", &a2, &a1, unify_one(&a2, &a1));
  130. let a1 = Term::Ter(Id(Rc::new("f".to_owned())), vec![Term::Ter(Id(Rc::new("int".to_owned())), Vec::new()), Term::Var(Id(Rc::new("a".to_owned()))), Term::Var(Id(Rc::new("b".to_owned()))), Term::Var(Id(Rc::new("gg".to_owned())))]);
  131. let a2 = Term::Ter(Id(Rc::new("f".to_owned())), vec![Term::Var(Id(Rc::new("b".to_owned()))), Term::Ter(Id(Rc::new("mat".to_owned())), Vec::new()), Term::Var(Id(Rc::new("c".to_owned()))), Term::Var(Id(Rc::new("gg".to_owned())))]);
  132. println!("{:?} -- {:?} ---> {:?}", &a1, &a2, unify_one(&a1, &a2));
  133. }