fix unification bugs.
This commit is contained in:
14
README.md
14
README.md
@@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user