]> Repositorios git - scryer-prolog.git/commitdiff
fix unification bugs. l0_final origin/l0_final
authorMark Thom <[email protected]>
Sat, 28 Jan 2017 04:54:53 +0000 (21:54 -0700)
committerMark Thom <[email protected]>
Sat, 28 Jan 2017 04:54:53 +0000 (21:54 -0700)
README.md
src/l0/machine.rs

index 7d00f4ad66881d24bc22a2b34d473c3351aed054..fff321ecc7ba317b0e4653b7b18c16495ab8ee19 100644 (file)
--- a/README.md
+++ b/README.md
@@ -26,7 +26,19 @@ yes
 l0> ?- p(z, w).  
 no  
 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)).  
 no  
 l0> p(Z, h(Z, W), f(W)).  
@@ -38,7 +50,9 @@ yes
 l0> ?- p(Z, h(z, W), f(w)).  
 yes  
 l0> ?- p(z, h(Z, w), f(w)).  
-yes  
+yes
+l0> ?- p(z, h(Z, w), f(Z)).
+no
 l0> quit
 ```
 
index 39099e07bf4d8275f563b63454aebb84d2d205b4..4855b26f828e9bffc3a37845e84c0919b6571bc1 100644 (file)
@@ -32,12 +32,12 @@ pub struct Machine {
 impl Machine {
     pub fn new() -> Machine {
         Machine { h : 0,
-                       s : 0,
-                       fail : false,
-                       heap : Vec::with_capacity(256),
-                       mode : MachineMode::Write,
-                       program : None,
-                       registers : vec![HeapCell::Ref(0); 33] }
+                  s : 0,
+                  fail : false,
+                  heap : Vec::with_capacity(256),
+                  mode : MachineMode::Write,
+                  program : None,
+                  registers : vec![HeapCell::Ref(0); 33] }
     }
     
     fn lookup(&self, a: Addr) -> &HeapCell {
@@ -64,11 +64,44 @@ 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) {
-        match a {
-            Addr::RegNum(reg)  => self.registers[reg] = HeapCell::Ref(val),
-            Addr::HeapCell(hc) => self.heap[hc] = HeapCell::Ref(val),
-        };
+        let mut a = a;
+        
+        loop {
+            match a {
+                Addr::RegNum(reg) => {
+                    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) {
@@ -152,13 +185,13 @@ impl Machine {
                             }
                         }
                     },
-                    &HeapCell::Ref(reg) => {
+                    &HeapCell::Ref(r) => {
                         self.heap.push(HeapCell::Str(self.h + 1));
                         self.heap.push(HeapCell::NamedStr(arity, name.clone()));
 
                         let h = self.h;
 
-                        self.bind(Addr::RegNum(reg), h);
+                        self.bind(Addr::HeapCell(r), h);
 
                         self.h += 2;
                         self.mode = MachineMode::Write;