From 3cfbbb23a393483cdea2f085cf3a53ee3a4ada9e Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 3 Feb 2019 15:16:30 -0700 Subject: [PATCH] introduce a better binding scheme for attributed variables --- src/prolog/copier.rs | 6 +- src/prolog/heap_iter.rs | 3 +- src/prolog/heap_print.rs | 2 +- src/prolog/instructions.rs | 26 +++--- src/prolog/machine/machine_state_impl.rs | 110 ++++++++++++++--------- src/prolog/machine/mod.rs | 8 +- src/prolog/machine/system_calls.rs | 41 ++++----- src/prolog/write.rs | 2 +- src/tests.rs | 29 +++--- 9 files changed, 122 insertions(+), 105 deletions(-) diff --git a/src/prolog/copier.rs b/src/prolog/copier.rs index 7efefef1..f5497529 100644 --- a/src/prolog/copier.rs +++ b/src/prolog/copier.rs @@ -22,7 +22,7 @@ pub(crate) trait CopierTarget: IndexMut { for (r, hcv) in redirect.trail { match r { - Ref::HeapCell(hc) => self[hc] = hcv.clone(), + Ref::AttrVar(hc) | Ref::HeapCell(hc) => self[hc] = hcv.clone(), Ref::StackCell(fr, sc) => self.stack()[fr][sc] = hcv.as_addr(0) } } @@ -100,12 +100,12 @@ pub(crate) trait CopierTarget: IndexMut scan += 1; }, - Addr::AttrVar(..) | Addr::HeapCell(_) | Addr::StackCell(_, _) => { + Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => { let ra = a; let rd = self.store(self.deref(ra.clone())); match rd.clone() { - Addr::AttrVar(h, _) | Addr::HeapCell(h) if h >= old_h => { + Addr::AttrVar(h) | Addr::HeapCell(h) if h >= old_h => { self[scan] = HeapCellValue::Addr(rd); scan += 1; }, diff --git a/src/prolog/heap_iter.rs b/src/prolog/heap_iter.rs index eb4dfe61..2b96ff69 100644 --- a/src/prolog/heap_iter.rs +++ b/src/prolog/heap_iter.rs @@ -65,8 +65,7 @@ impl<'a> HCPreOrderIterator<'a> { da }, - Addr::HeapCell(_) | Addr::StackCell(_, _) => da, - Addr::AttrVar(h, _) => self.follow_heap(h + 1), + Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => da, Addr::Str(s) => self.follow_heap(s) // record terms of structure. } } diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 86f946d0..76ec3b01 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -373,7 +373,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> fn offset_as_string(&self, addr: Addr) -> Option { match addr { - Addr::AttrVar(h, _) => + Addr::AttrVar(h) => Some(format!("_{}", h + 1)), Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) => Some(format!("_{}", h)), diff --git a/src/prolog/instructions.rs b/src/prolog/instructions.rs index f1f12d93..1cf71750 100644 --- a/src/prolog/instructions.rs +++ b/src/prolog/instructions.rs @@ -717,7 +717,7 @@ pub type CodeDeque = VecDeque; #[derive(Clone, PartialEq, Eq, Hash)] pub enum Addr { - AttrVar(usize, usize), // the location of the AttrVal in the heap, the location of the attribute list. + AttrVar(usize), Con(Constant), Lis(usize), HeapCell(usize), @@ -737,7 +737,8 @@ impl PartialOrd for Addr { match self { &Addr::StackCell(fr, sc) => match *r { - Ref::HeapCell(_) => Some(Ordering::Greater), + Ref::AttrVar(_) | Ref::HeapCell(_) => + Some(Ordering::Greater), Ref::StackCell(fr1, sc1) => if fr1 < fr || (fr1 == fr && sc1 < sc) { Some(Ordering::Greater) @@ -747,10 +748,10 @@ impl PartialOrd for Addr { Some(Ordering::Less) } }, - &Addr::HeapCell(h) | &Addr::AttrVar(h, _) => + &Addr::HeapCell(h) | &Addr::AttrVar(h) => match r { &Ref::StackCell(..) => Some(Ordering::Less), - &Ref::HeapCell(h1) => h.partial_cmp(&h1) + &Ref::AttrVar(h1) | &Ref::HeapCell(h1) => h.partial_cmp(&h1) }, _ => None } @@ -760,14 +761,14 @@ impl PartialOrd for Addr { impl Addr { pub fn is_ref(&self) -> bool { match self { - &Addr::AttrVar(..) | &Addr::HeapCell(_) | &Addr::StackCell(_, _) => true, + &Addr::AttrVar(_) | &Addr::HeapCell(_) | &Addr::StackCell(_, _) => true, _ => false } } pub fn as_var(&self) -> Option { match self { - &Addr::AttrVar(h, _) => Some(Ref::HeapCell(h)), + &Addr::AttrVar(h) => Some(Ref::AttrVar(h)), &Addr::HeapCell(h) => Some(Ref::HeapCell(h)), &Addr::StackCell(fr, sc) => Some(Ref::StackCell(fr, sc)), _ => None @@ -788,6 +789,7 @@ impl Add for Addr { fn add(self, rhs: usize) -> Self::Output { match self { Addr::Lis(a) => Addr::Lis(a + rhs), + Addr::AttrVar(h) => Addr::AttrVar(h + rhs), Addr::HeapCell(h) => Addr::HeapCell(h + rhs), Addr::Str(s) => Addr::Str(s + rhs), _ => self @@ -801,6 +803,7 @@ impl Sub for Addr { fn sub(self, rhs: usize) -> Self::Output { match self { Addr::Lis(a) => Addr::Lis(a - rhs), + Addr::AttrVar(h) => Addr::AttrVar(h - rhs), Addr::HeapCell(h) => Addr::HeapCell(h - rhs), Addr::Str(s) => Addr::Str(s - rhs), _ => self @@ -811,6 +814,7 @@ impl Sub for Addr { impl From for Addr { fn from(r: Ref) -> Self { match r { + Ref::AttrVar(h) => Addr::AttrVar(h), Ref::HeapCell(h) => Addr::HeapCell(h), Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc) } @@ -819,6 +823,7 @@ impl From for Addr { #[derive(Clone, Copy, Hash, Eq, PartialEq)] pub enum Ref { + AttrVar(usize), HeapCell(usize), StackCell(usize, usize) } @@ -826,6 +831,7 @@ pub enum Ref { impl Ref { pub fn as_addr(self) -> Addr { match self { + Ref::AttrVar(h) => Addr::AttrVar(h), Ref::HeapCell(h) => Addr::HeapCell(h), Ref::StackCell(fr, sc) => Addr::StackCell(fr, sc) } @@ -834,17 +840,13 @@ impl Ref { #[derive(Clone)] pub enum TrailRef { - HeapCell(usize), - StackCell(usize, usize), + Ref(Ref), AttrVarLink(usize, Addr) } impl From for TrailRef { fn from(r: Ref) -> Self { - match r { - Ref::HeapCell(h) => TrailRef::HeapCell(h), - Ref::StackCell(fr, sc) => TrailRef::StackCell(fr, sc) - } + TrailRef::Ref(r) } } diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 11a41941..6c1374bf 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -76,28 +76,47 @@ impl MachineState { if self.b > 0 { self.or_stack[self.b - 1].global_index } else { 0 }) + 1 } - pub(crate) fn store(&self, a: Addr) -> Addr { - match a { - Addr::AttrVar(h, _) => self.heap[h].as_addr(h), - Addr::HeapCell(h) => self.heap[h].as_addr(h), + pub(crate) fn store(&self, addr: Addr) -> Addr { + match addr { + Addr::AttrVar(h) | Addr::HeapCell(h) => self.heap[h].as_addr(h), Addr::StackCell(fr, sc) => self.and_stack[fr][sc].clone(), - addr => addr + addr => addr } } - pub(crate) fn deref(&self, mut a: Addr) -> Addr { + pub(crate) fn deref(&self, mut addr: Addr) -> Addr { loop { - let value = self.store(a.clone()); + let value = self.store(addr.clone()); - if value.is_ref() && value != a { - a = value; + if value.is_ref() && value != addr { + addr = value; continue; } - return a; + return addr; }; } + // from the assumptions active at the call site in bind, we know: + // if addr is a Ref, it precedes h in the heap. + fn bind_attr_var(&mut self, h: usize, addr: Addr) { + match addr.as_var() { + Some(Ref::HeapCell(hc)) => { + self.heap[hc] = HeapCellValue::Addr(Addr::AttrVar(h)); + self.trail(TrailRef::from(Ref::HeapCell(hc))); + }, + Some(Ref::StackCell(fr, sc)) => { + self.and_stack[fr][sc] = Addr::AttrVar(h); + self.trail(TrailRef::from(Ref::StackCell(fr, sc))); + }, + _ => { + // TODO: set up writing to the attribute queue here. + self.heap[h] = HeapCellValue::Addr(addr); + self.trail(TrailRef::from(Ref::AttrVar(h))); + } + } + } + pub(super) fn bind(&mut self, r1: Ref, a2: Addr) { let t1 = self.store(r1.as_addr()); let t2 = self.store(a2.clone()); @@ -107,7 +126,9 @@ impl MachineState { Ref::StackCell(fr, sc) => self.and_stack[fr][sc] = t2, Ref::HeapCell(h) => - self.heap[h] = HeapCellValue::Addr(t2) + self.heap[h] = HeapCellValue::Addr(t2), + Ref::AttrVar(h) => + return self.bind_attr_var(h, t2) }; self.trail(TrailRef::from(r1)); @@ -115,12 +136,14 @@ impl MachineState { match a2.as_var() { Some(Ref::StackCell(fr, sc)) => { self.and_stack[fr][sc] = t1; - self.trail(TrailRef::StackCell(fr, sc)); + self.trail(TrailRef::Ref(Ref::StackCell(fr, sc))); }, Some(Ref::HeapCell(h)) => { self.heap[h] = HeapCellValue::Addr(t1); - self.trail(TrailRef::HeapCell(h)); + self.trail(TrailRef::Ref(Ref::HeapCell(h))); }, + Some(Ref::AttrVar(h)) => + return self.bind_attr_var(h, t1), None => {} } } @@ -220,10 +243,8 @@ impl MachineState { if d1 != d2 { match (self.store(d1.clone()), self.store(d2.clone())) { - (Addr::AttrVar(h, _), addr) | (addr, Addr::AttrVar(h, _)) => { - pdl.push(Addr::HeapCell(h+1)); - pdl.push(addr); - }, + (Addr::AttrVar(h), addr) | (addr, Addr::AttrVar(h)) => + self.bind(Ref::AttrVar(h), addr), (Addr::HeapCell(h), _) => self.bind(Ref::HeapCell(h), d2), (_, Addr::HeapCell(h)) => @@ -354,9 +375,14 @@ impl MachineState { pub(super) fn trail(&mut self, r: TrailRef) { match r { - TrailRef::HeapCell(h) => + TrailRef::Ref(Ref::HeapCell(h)) => + if h < self.hb { + self.trail.push(TrailRef::Ref(Ref::HeapCell(h))); + self.tr += 1; + }, + TrailRef::Ref(Ref::AttrVar(h)) => if h < self.hb { - self.trail.push(TrailRef::HeapCell(h)); + self.trail.push(TrailRef::Ref(Ref::AttrVar(h))); self.tr += 1; }, TrailRef::AttrVarLink(h, prev_addr) => @@ -364,7 +390,7 @@ impl MachineState { self.trail.push(TrailRef::AttrVarLink(h, prev_addr)); self.tr += 1; }, - TrailRef::StackCell(fr, sc) => { + TrailRef::Ref(Ref::StackCell(fr, sc)) => { let fr_gi = self.and_stack[fr].global_index; let b_gi = if !self.or_stack.is_empty() { if self.b > 0 { @@ -378,7 +404,7 @@ impl MachineState { }; if fr_gi < b_gi { - self.trail.push(TrailRef::StackCell(fr, sc)); + self.trail.push(TrailRef::Ref(Ref::StackCell(fr, sc))); self.tr += 1; } } @@ -391,9 +417,11 @@ impl MachineState { // backtracking. for i in (a1 .. a2).rev() { match self.trail[i].clone() { - TrailRef::HeapCell(h) => + TrailRef::Ref(Ref::HeapCell(h)) => self.heap[h] = HeapCellValue::Addr(Addr::HeapCell(h)), - TrailRef::StackCell(fr, sc) => + TrailRef::Ref(Ref::AttrVar(h)) => + self.heap[h] = HeapCellValue::Addr(Addr::AttrVar(h)), + TrailRef::Ref(Ref::StackCell(fr, sc)) => self.and_stack[fr][sc] = Addr::StackCell(fr, sc), TrailRef::AttrVarLink(h, prev_addr) => self.heap[h] = HeapCellValue::Addr(prev_addr) @@ -443,7 +471,9 @@ impl MachineState { let hb = self.hb; match tr_i { - TrailRef::HeapCell(tr_i) | TrailRef::AttrVarLink(tr_i, _) => + TrailRef::Ref(Ref::AttrVar(tr_i)) + | TrailRef::Ref(Ref::HeapCell(tr_i)) + | TrailRef::AttrVarLink(tr_i, _) => if tr_i < hb { i += 1; } else { @@ -453,7 +483,7 @@ impl MachineState { self.trail.pop(); self.tr -= 1; }, - TrailRef::StackCell(fr, _) => { + TrailRef::Ref(Ref::StackCell(fr, _)) => { let b = self.b - 1; let fr_gi = self.and_stack[fr].global_index; let b_gi = if !self.or_stack.is_empty() { @@ -489,11 +519,11 @@ impl MachineState { match self.store(self.deref(addr)) { Addr::HeapCell(h) => { self.heap[h] = HeapCellValue::Addr(Addr::Con(c.clone())); - self.trail(TrailRef::HeapCell(h)); + self.trail(TrailRef::Ref(Ref::HeapCell(h))); }, Addr::StackCell(fr, sc) => { self.and_stack[fr][sc] = Addr::Con(c.clone()); - self.trail(TrailRef::StackCell(fr, sc)); + self.trail(TrailRef::Ref(Ref::StackCell(fr, sc))); }, Addr::Con(Constant::String(ref mut s)) => self.fail = match c { @@ -1012,19 +1042,11 @@ impl MachineState { self.fail = true; } }, - Addr::HeapCell(hc) => { - let h = self.heap.h; - - self.heap.push(HeapCellValue::Addr(Addr::Lis(h+1))); - self.bind(Ref::HeapCell(hc), Addr::HeapCell(h)); - - self.mode = MachineMode::Write; - }, - Addr::StackCell(fr, sc) => { + addr @ Addr::AttrVar(_) | addr @ Addr::StackCell(..) | addr @ Addr::HeapCell(_) => { let h = self.heap.h; self.heap.push(HeapCellValue::Addr(Addr::Lis(h+1))); - self.bind(Ref::StackCell(fr, sc), Addr::HeapCell(h)); + self.bind(addr.as_var().unwrap(), Addr::HeapCell(h)); self.mode = MachineMode::Write; }, @@ -1051,7 +1073,7 @@ impl MachineState { } } }, - Addr::HeapCell(_) | Addr::StackCell(_, _) => { + Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => { let h = self.heap.h; self.heap.push(HeapCellValue::Addr(Addr::Str(h + 1))); @@ -1788,8 +1810,8 @@ impl MachineState { let d = self.store(self.deref(self[r1].clone())); match d { - Addr::HeapCell(_) | Addr::StackCell(..) => self.fail = true, - Addr::AttrVar(h, _) => { + Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(..) => self.fail = true, +/* Addr::AttrVar(h) => { let addr = self.heap[h].as_addr(h); if let Some(_) = addr.as_var() { @@ -1799,7 +1821,7 @@ impl MachineState { } self.p += 1; - }, + },*/ _ => self.p += 1 }; }, @@ -1807,8 +1829,8 @@ impl MachineState { let d = self.store(self.deref(self[r1].clone())); match d { - Addr::HeapCell(_) | Addr::StackCell(_,_) => self.p += 1, - Addr::AttrVar(h, _) => { + Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_,_) => self.p += 1, +/* Addr::AttrVar(h, _) => { let addr = self.heap[h].as_addr(h); if let Some(_) = addr.as_var() { @@ -1818,7 +1840,7 @@ impl MachineState { } self.p += 1; - }, + },*/ _ => self.fail = true }; }, diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 3e31e48e..1b8ca01a 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -431,7 +431,7 @@ impl Machine { let mut heap_locs = HashMap::new(); self.code_repo.cached_query = code; - self.machine_st.run_query(&mut self.indices, &mut self.policies, &self.code_repo, + self.machine_st.run_query(&mut self.indices, &mut self.policies, &mut self.code_repo, &alloc_locs, &mut heap_locs); if self.machine_st.fail { @@ -451,7 +451,7 @@ impl Machine { return EvalSession::from(SessionError::QueryFailure); } - self.machine_st.run_query(&mut self.indices, &mut self.policies, &self.code_repo, + self.machine_st.run_query(&mut self.indices, &mut self.policies, &mut self.code_repo, alloc_l, heap_l); if self.machine_st.fail { @@ -560,7 +560,7 @@ impl MachineState { } fn query_stepper(&mut self, indices: &mut IndexStore, policies: &mut MachinePolicies, - code_repo: &CodeRepo) + code_repo: &mut CodeRepo) { loop { self.execute_instr(indices, policies, code_repo); @@ -617,7 +617,7 @@ impl MachineState { pub(super) fn run_query(&mut self, indices: &mut IndexStore, - policies: &mut MachinePolicies, code_repo: &CodeRepo, + policies: &mut MachinePolicies, code_repo: &mut CodeRepo, alloc_locs: &AllocVarDict, heap_locs: &mut HeapVarDict) { let end_ptr = top_level_code_ptr!(0, code_repo.size_of_cached_query()); diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index b7e5d15e..b6df24b8 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -208,24 +208,24 @@ impl MachineState { if let Addr::Lis(l1) = ls0 { if let Addr::Lis(l2) = self.store(self.deref(Addr::HeapCell(l1 + 1))) { - let addr = self.heap[l1 + 1].as_addr(l1 + 1); + let addr = self.heap[l1 + 1].as_addr(l1 + 1); self.heap[l1 + 1] = HeapCellValue::Addr(Addr::HeapCell(l2 + 1)); self.trail(TrailRef::AttrVarLink(l1 + 1, addr)); } - } + } }, &SystemClauseType::DeleteHeadAttribute => { let addr = self.store(self.deref(self[temp_v!(1)].clone())); - + match addr { - Addr::AttrVar(_, attr_var) => { - let addr = self.heap[attr_var].as_addr(attr_var).clone(); + Addr::AttrVar(h) => { + let addr = self.heap[h+1].as_addr(h+1).clone(); let addr = self.store(self.deref(addr)); - + match addr { Addr::Lis(l) => { - self.heap[attr_var] = HeapCellValue::Addr(Addr::HeapCell(l+1)); - self.trail(TrailRef::AttrVarLink(attr_var, Addr::Lis(l))); + self.heap[h+1] = HeapCellValue::Addr(Addr::HeapCell(l+1)); + self.trail(TrailRef::AttrVarLink(h+1, Addr::Lis(l))); }, _ => {} } @@ -270,27 +270,16 @@ impl MachineState { &SystemClauseType::GetAttributedVariableList => { let attr_var = self.store(self.deref(self[temp_v!(1)].clone())); let mut attr_var_list = match attr_var { - Addr::AttrVar(_, attr_var_list) => attr_var_list, + Addr::AttrVar(h) => h + 1, attr_var @ Addr::HeapCell(_) | attr_var @ Addr::StackCell(..) => { // create an AttrVar in the heap. let h = self.heap.h; - - self.heap.push(HeapCellValue::Addr(Addr::AttrVar(h, h + 2))); - self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + 1))); - self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + 2))); - match attr_var.as_var().unwrap() { - Ref::HeapCell(r) => { - self.heap[r] = HeapCellValue::Addr(Addr::HeapCell(h)); - self.trail(TrailRef::HeapCell(r)); - }, - Ref::StackCell(fr, sc) => { - self.and_stack[fr][sc] = Addr::HeapCell(h); - self.trail(TrailRef::StackCell(fr, sc)); - } - } + self.heap.push(HeapCellValue::Addr(Addr::AttrVar(h))); + self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + 1))); - h + 2 + self.bind(Ref::AttrVar(h), attr_var); + h + 1 }, _ => { self.fail = true; @@ -298,8 +287,8 @@ impl MachineState { } }; - let list_var = self[temp_v!(2)].clone(); - self.unify(Addr::HeapCell(attr_var_list), list_var); + let list_addr = self[temp_v!(2)].clone(); + self.unify(Addr::HeapCell(attr_var_list), list_addr); }, &SystemClauseType::GetDoubleQuotes => { let a1 = self[temp_v!(1)].clone(); diff --git a/src/prolog/write.rs b/src/prolog/write.rs index e54d8527..87a6adaf 100644 --- a/src/prolog/write.rs +++ b/src/prolog/write.rs @@ -146,7 +146,7 @@ impl fmt::Display for Addr { match self { &Addr::Con(ref c) => write!(f, "Addr::Con({})", c), &Addr::Lis(l) => write!(f, "Addr::Lis({})", l), - &Addr::AttrVar(h, attr_var_list) => write!(f, "Addr::AttrVar({}, {})", h, attr_var_list), + &Addr::AttrVar(h) => write!(f, "Addr::AttrVar({})", h), &Addr::HeapCell(h) => write!(f, "Addr::HeapCell({})", h), &Addr::StackCell(fr, sc)=> write!(f, "Addr::StackCell({}, {})", fr, sc), &Addr::Str(s) => write!(f, "Addr::Str({})", s) diff --git a/src/tests.rs b/src/tests.rs index 89c8f1b8..646e8f9b 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -2147,28 +2147,33 @@ fn test_queries_on_attributed_variables() assert_prolog_success!(&mut wam, "?- ( put_atts(V, my_mod, dif(1)) ; put_atts(V, my_mod, dif(2)) ), get_atts(V, my_mod, L).", - [["L = [dif(1) | _17]", "V = _12"], - ["L = [dif(2) | _17]", "V = _12"]]); + [["L = [dif(1) | _16]", "V = _12"], + ["L = [dif(2) | _16]", "V = _12"]]); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, frozen(a)), ( put_atts(V, my_mod, dif(1)) ; put_atts(V, my_mod, -frozen(a)), put_atts(V, my_mod, dif(2)) ; put_atts(V, my_mod, dif(different)) ), get_atts(V, my_mod, Ls).", - [["Ls = [frozen(a), dif(1) | _37]", "V = _12"], - ["Ls = [dif(2) | _51]", "V = _12"], - ["Ls = [frozen(a), dif(different) | _37]", "V = _12"]]); + [["Ls = [frozen(a), dif(1) | _36]", "V = _12"], + ["Ls = [dif(2) | _50]", "V = _12"], + ["Ls = [frozen(a), dif(different) | _36]", "V = _12"]]); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a)]), - ( put_atts(V, my_mod, -dif(2)) ; put_atts(V, my_mod, -frozen(A)) ), + ( put_atts(V, my_mod, -dif(2)); put_atts(V, my_mod, -frozen(A)) ), get_atts(V, my_mod, L).", - [["A = _70", "L = [dif(1), frozen(a) | _68]", "V = _27"], - ["A = _70", "L = [dif(1), dif(2) | _68]", "V = _27"]]); + [["A = _69", "L = [dif(1), frozen(a) | _67]", "V = _27"], + ["A = _69", "L = [dif(1), dif(2) | _67]", "V = _27"]]); + assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a)]), + ( put_atts(V, my_mod, -dif(2)), V = f(a) + ; put_atts(V, my_mod, -frozen(_)), get_atts(V, my_mod, L) ).", + [["L = _69", "V = f(a)"], + ["L = [dif(1), dif(2) | _67]", "V = _27"]]); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), ( put_atts(V, my_mod, -dif(2)) ; put_atts(V, my_mod, -frozen(A)) ), get_atts(V, my_mod, L).", - [["A = _98", "L = [dif(1), frozen(a), frozen(b) | _96]", "V = _31"], - ["A = _98", "L = [dif(1), dif(2) | _96]", "V = _31"]]); + [["A = _97", "L = [dif(1), frozen(a), frozen(b) | _95]", "V = _31"], + ["A = _97", "L = [dif(1), dif(2) | _95]", "V = _31"]]); assert_prolog_failure!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), get_atts(V, my_mod, -dif(1))."); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), @@ -2179,8 +2184,8 @@ fn test_queries_on_attributed_variables() ["X = 2", "V = _31"]]); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), dif(2), frozen(a), frozen(b)]), put_atts(V, my_mod, -dif(A)), get_atts(V, my_mod, Ls).", - [["A = _99", "Ls = [frozen(a), frozen(b) | _96]", "V = _31"]]); + [["A = _98", "Ls = [frozen(a), frozen(b) | _95]", "V = _31"]]); assert_prolog_success!(&mut wam, "?- put_atts(V, my_mod, [dif(1), frozen(a), dif(2), frozen(b)]), put_atts(V, my_mod, -dif(A)), get_atts(V, my_mod, Ls).", - [["A = _99", "Ls = [frozen(a), frozen(b) | _96]", "V = _31"]]); + [["A = _98", "Ls = [frozen(a), frozen(b) | _95]", "V = _31"]]); } -- 2.54.0