fix unification bugs.

This commit is contained in:
Mark Thom
2017-01-27 21:54:53 -07:00
parent e7af3dc57a
commit 0c6926b3cb
2 changed files with 61 additions and 14 deletions

View File

@@ -27,6 +27,18 @@ l0> ?- p(z, w).
no no
l0> ?- p(w, w). l0> ?- p(w, w).
yes yes
l0> clouds(are, nice).
Program stored.
l0> ?- clouds(Z, Z).
no
l0> ?- clouds(Z, W).
yes
l0> ?- clouds(are, W).
yes
l0> ?- clouds(W, nice).
yes
l0> ?- clouds(nice, are).
no
l0> ?- p(Z, h(Z, W), f(W)). l0> ?- p(Z, h(Z, W), f(W)).
no no
l0> p(Z, h(Z, W), f(W)). l0> p(Z, h(Z, W), f(W)).
@@ -39,6 +51,8 @@ l0> ?- p(Z, h(z, W), f(w)).
yes yes
l0> ?- p(z, h(Z, w), f(w)). l0> ?- p(z, h(Z, w), f(w)).
yes yes
l0> ?- p(z, h(Z, w), f(Z)).
no
l0> quit l0> quit
``` ```

View File

@@ -64,12 +64,45 @@ impl Machine {
}; };
} }
fn is_unbound(hc: &HeapCell, index: usize) -> bool {
match hc {
&HeapCell::Ref(r) => r == index,
_ => false
}
}
//TODO: try to compress this function. currently it is dog shit.
fn bind(&mut self, a: Addr, val: usize) { fn bind(&mut self, a: Addr, val: usize) {
let mut a = a;
loop {
match a { match a {
Addr::RegNum(reg) => self.registers[reg] = HeapCell::Ref(val), Addr::RegNum(reg) => {
Addr::HeapCell(hc) => self.heap[hc] = HeapCell::Ref(val), if let HeapCell::Ref(hc) = self.registers[reg] {
a = Addr::HeapCell(hc);
} else if Machine::is_unbound(&self.heap[val], val) {
self.heap[val] = self.registers[reg].clone();
break;
} else {
self.fail = true;
break;
}
},
Addr::HeapCell(hc) if Machine::is_unbound(&self.heap[hc], hc) => {
self.heap[hc] = HeapCell::Ref(val);
break;
},
Addr::HeapCell(hc) if Machine::is_unbound(&self.heap[val], val) => {
self.heap[val] = HeapCell::Ref(hc);
break;
},
_ => {
self.fail = true;
break;
}
}; };
} }
}
fn unify(&mut self, a1: Addr, a2: Addr) { fn unify(&mut self, a1: Addr, a2: Addr) {
let mut pdl : Vec<Addr> = vec![a1, a2]; let mut pdl : Vec<Addr> = vec![a1, a2];
@@ -152,13 +185,13 @@ impl Machine {
} }
} }
}, },
&HeapCell::Ref(reg) => { &HeapCell::Ref(r) => {
self.heap.push(HeapCell::Str(self.h + 1)); self.heap.push(HeapCell::Str(self.h + 1));
self.heap.push(HeapCell::NamedStr(arity, name.clone())); self.heap.push(HeapCell::NamedStr(arity, name.clone()));
let h = self.h; let h = self.h;
self.bind(Addr::RegNum(reg), h); self.bind(Addr::HeapCell(r), h);
self.h += 2; self.h += 2;
self.mode = MachineMode::Write; self.mode = MachineMode::Write;