mini_kanren/core/
value.rs1use crate::core::logic_variable::{ReifiedVar, Var};
3use crate::core::pair::Pair;
4use crate::core::structure::{Atomic, Structure};
5use crate::core::substitution::Substitution;
6use std::fmt::Formatter;
7use std::sync::Arc;
8
9#[derive(Clone)]
11pub struct Value(Arc<dyn Structure>);
12
13impl PartialEq for Value {
14 fn eq(&self, other: &Self) -> bool {
15 Arc::ptr_eq(&self.0, &other.0) || self.0.eqv(&other)
16 }
17}
18
19impl Value {
20 pub fn new(val: impl Into<Value>) -> Self {
22 val.into()
23 }
24
25 pub fn from_arc<T: Structure>(x: Arc<T>) -> Self {
27 Value(x)
28 }
29
30 pub fn var(v: Var) -> Self {
32 Value::new(v)
33 }
34
35 pub fn rv(i: usize) -> Self {
37 Value::new(ReifiedVar(i))
38 }
39
40 pub fn cons(car: impl Into<Value>, cdr: impl Into<Value>) -> Self {
42 Value::new((car.into(), cdr.into()))
43 }
44
45 pub fn try_as_var(&self) -> Option<Var> {
47 self.downcast_ref().copied()
48 }
49
50 pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
52 self.0.as_any().downcast_ref()
53 }
54
55 pub(super) fn occurs<'s>(&self, x: &Var, s: &Substitution<'s>) -> bool {
56 self.0.occurs(x, s)
57 }
58
59 pub(super) fn unify<'s>(&self, v: &Value, s: Substitution<'s>) -> Option<Substitution<'s>> {
60 self.0.unify(v, s)
61 }
62
63 pub(super) fn walk_star(&self, s: &Substitution<'_>) -> Value {
64 self.0.clone().walk_star(s)
65 }
66
67 pub(super) fn reify_s<'s>(&self, s: Substitution<'s>) -> Substitution<'s> {
68 self.0.reify_s(s)
69 }
70}
71
72impl PartialEq<Var> for Value {
73 fn eq(&self, v: &Var) -> bool {
74 self.0
75 .as_any()
76 .downcast_ref::<Var>()
77 .map(|sv| sv == v)
78 .unwrap_or(false)
79 }
80}
81
82impl<T: Structure> From<T> for Value {
83 fn from(v: T) -> Self {
84 Value(Arc::new(v))
85 }
86}
87
88impl<T: 'static + Atomic + PartialEq> PartialEq<T> for Value {
89 fn eq(&self, other: &T) -> bool {
90 self.0
91 .as_any()
92 .downcast_ref::<T>()
93 .map(|x| x == other)
94 .unwrap_or(false)
95 }
96}
97
98impl std::fmt::Debug for Value {
99 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
100 write!(f, "{:?}", self.0)
101 }
102}
103
104impl From<Vec<Value>> for Value {
105 fn from(items: Vec<Value>) -> Self {
107 let mut list = Value::from(());
108 for v in items.into_iter().rev() {
109 list = Value::cons(v, list);
110 }
111 list
112 }
113}
114
115impl<A: Into<Value>, D: Into<Value>> From<(A, D)> for Value {
116 fn from(pair: (A, D)) -> Self {
117 let pair = (pair.0.into(), pair.1.into());
118 Value::new(Pair::from(pair))
119 }
120}