mod get;
mod member;
mod slice;
mod subset;
use crate::{
core::{Reify, State, Unify, Value},
ReadyState,
};
pub use get::{get, Get};
pub use member::{member, Member};
pub use slice::{slice, Slice};
pub use subset::{subset, Subset};
use std::rc::Rc;
#[derive(Debug)]
pub struct LVec<T: Unify> {
vec: Vec<Value<T>>,
}
impl<T: Unify> LVec<T> {
pub fn len(&self) -> usize {
self.vec.len()
}
pub fn is_empty(&self) -> bool {
self.vec.is_empty()
}
}
#[macro_export]
macro_rules! lvec {
($($item:expr),* $(,)?) => {
{
let vec = vec![$($item.into(),)*];
$crate::collections::lvec::LVec::from(vec)
}
};
}
impl<T: Unify> Unify for LVec<T> {
fn unify(state: State, a: Rc<Self>, b: Rc<Self>) -> Option<State> {
if a.vec.len() == b.vec.len() {
a.vec
.iter()
.zip(b.vec.iter())
.try_fold(state, |s: State, (a, b)| s.unify(a, b))
} else {
None
}
}
}
impl<T: Unify + Reify> Reify for LVec<T> {
type Reified = Vec<T::Reified>;
fn reify_in(&self, state: &ReadyState) -> Option<Vec<T::Reified>> {
self.vec
.iter()
.map(|v: &Value<T>| v.reify_in(state))
.collect()
}
}
impl<T: Unify> From<Vec<Value<T>>> for LVec<T> {
fn from(vec: Vec<Value<T>>) -> Self {
LVec { vec }
}
}
impl<T: Unify> From<&[Value<T>]> for LVec<T> {
fn from(slice: &[Value<T>]) -> Self {
LVec {
vec: slice.to_vec(),
}
}
}
impl<T: Unify> FromIterator<Value<T>> for LVec<T> {
fn from_iter<I: IntoIterator<Item = Value<T>>>(iter: I) -> Self {
LVec {
vec: iter.into_iter().collect(),
}
}
}
impl<T: Unify> FromIterator<T> for LVec<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
LVec {
vec: iter.into_iter().map(Value::new).collect(),
}
}
}
#[cfg(test)]
mod tests {
use crate::{core::LVar, core::Query, goals::unify, lvec::LVec, Value};
#[test]
fn succeeds() {
let x = LVar::new();
let goal = unify(lvec![x, 2], lvec![1, 2]);
assert_eq!(goal.query(x).collect::<Vec<_>>(), vec![1]);
}
#[test]
fn fails() {
let x = LVar::new();
let goal = unify(lvec![x, 1], lvec![1, 2]);
assert_eq!(goal.query(x).count(), 0);
}
#[test]
fn is_empty() {
let empty: LVec<usize> = lvec![];
assert!(empty.is_empty());
}
#[test]
fn from_iter_value_t() {
let from_iter: LVec<usize> = (1..3).collect();
assert_eq!(from_iter.vec, vec![Value::new(1), Value::new(2)]);
}
#[test]
fn from_iter_t() {
let from_iter: LVec<usize> = (1..3).map(Value::new).collect();
assert_eq!(from_iter.vec, vec![Value::new(1), Value::new(2)]);
}
}