suiron/
built_in_append.rs1use std::rc::Rc;
4
5use super::unifiable::*;
6use super::s_linked_list::*;
7use super::substitution_set::*;
8use super::built_in_predicates::*;
9
10pub fn next_solution_append<'a>(bip: BuiltInPredicate,
30 ss: &'a Rc<SubstitutionSet<'a>>)
31 -> Option<Rc<SubstitutionSet<'a>>> {
32
33 if let Some(terms) = bip.terms {
34
35 let length = terms.len();
36 if length < 2 { return None; }
37
38 let mut out_terms: Vec<Unifiable> = vec![];
39
40 for i in 0..(length - 1) {
41
42 let mut t = terms[i].clone();
43
44 if let Unifiable::LogicVar{id: _, name: _} = t {
46 match get_ground_term(&t, &ss) {
47 Some(new_term) => { t = new_term.clone(); },
48 None => {},
49 }
50 }
51
52 match t {
53 Unifiable::Nil |
54 Unifiable::Anonymous |
55 Unifiable::Atom(_) |
56 Unifiable::SInteger(_) |
57 Unifiable::SFloat(_) |
58 Unifiable::SFunction{name: _, terms: _} |
59 Unifiable::SComplex(_) => { out_terms.push(t); },
60 Unifiable::SLinkedList{term: _, next: _, count: _, tail_var: _} => {
61 let mut list = t;
62 loop {
63 if let Unifiable::SLinkedList{term, next,
64 count: _, tail_var: _} = list {
65 if *term == Unifiable::Nil { break; }
66 out_terms.push(*term);
67 list = *next;
68 }
69 }
70 },
71 Unifiable::LogicVar{id: _, name: _} => {},
73 } } let out = make_linked_list(false, out_terms);
78 let last_term = terms[length - 1].clone();
79
80 return last_term.unify(&out, &ss);
82 }
83 return None;
84
85} #[cfg(test)]
88mod test {
89
90 use std::rc::Rc;
91 use crate::*;
92 use super::*;
93
94 #[test]
96 fn test_append() {
97
98 let kb = KnowledgeBase::new();
99
100 let query = parse_query("go").unwrap();
102 let base_node = make_base_node(Rc::new(query), &kb);
103
104 let append_pred = match parse_subgoal(
106 "append(3.14159, [A, B, C], 6, $Out)") {
107 Ok(goal) => { goal },
108 Err(err) => { panic!("{}", err); },
109 };
110
111 let mut var_map = VarMap::new();
113 let append_pred = append_pred.recreate_variables(&mut var_map);
114
115 let sn = make_solution_node(Rc::new(append_pred), &kb,
117 empty_ss!(), base_node);
118
119 match next_solution(sn) {
121 Some(ss) => {
122 let term = ss[1].clone().unwrap();
123 let s = format!("{}", *term);
124 assert_eq!("[3.14159, A, B, C, 6]", s)
125 },
126 None => { panic!("Append() should join terms together."); },
127 } } }