introduce a better binding scheme for attributed variables
This commit is contained in:
@@ -22,7 +22,7 @@ pub(crate) trait CopierTarget: IndexMut<usize, Output=HeapCellValue>
|
||||
{
|
||||
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<usize, Output=HeapCellValue>
|
||||
|
||||
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;
|
||||
},
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
|
||||
|
||||
fn offset_as_string(&self, addr: Addr) -> Option<String> {
|
||||
match addr {
|
||||
Addr::AttrVar(h, _) =>
|
||||
Addr::AttrVar(h) =>
|
||||
Some(format!("_{}", h + 1)),
|
||||
Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) =>
|
||||
Some(format!("_{}", h)),
|
||||
|
||||
@@ -717,7 +717,7 @@ pub type CodeDeque = VecDeque<Line>;
|
||||
|
||||
#[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<Ref> 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<Ref> 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<Ref> 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<Ref> {
|
||||
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<usize> 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<usize> 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<usize> for Addr {
|
||||
impl From<Ref> 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<Ref> 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<Ref> 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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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::HeapCell(h));
|
||||
self.trail.push(TrailRef::Ref(Ref::HeapCell(h)));
|
||||
self.tr += 1;
|
||||
},
|
||||
TrailRef::Ref(Ref::AttrVar(h)) =>
|
||||
if h < self.hb {
|
||||
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) => {
|
||||
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::HeapCell(hc), Addr::HeapCell(h));
|
||||
|
||||
self.mode = MachineMode::Write;
|
||||
},
|
||||
Addr::StackCell(fr, sc) => {
|
||||
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
|
||||
};
|
||||
},
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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::AttrVar(h)));
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
29
src/tests.rs
29
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"]]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user