]> Repositorios git - scryer-prolog.git/commitdiff
add heapview, move registers to HeapCellRef
authorMark Thom <[email protected]>
Fri, 24 Feb 2017 23:16:14 +0000 (16:16 -0700)
committerMark Thom <[email protected]>
Fri, 24 Feb 2017 23:16:14 +0000 (16:16 -0700)
12 files changed:
Cargo.lock
Cargo.toml
README.md
src/l2/ast.rs
src/l2/codegen.rs
src/l2/heapview.rs [new file with mode: 0644]
src/l2/l2_parser.lalrpop
src/l2/l2_parser.rs
src/l2/machine.rs
src/l2/mod.rs
src/l2/stack.rs
src/main.rs

index b7dce60dbc5edcf389bb44f4c4c8b64dba6de707..c38c995f512fcb57933e95b80a1f0edd012db216 100644 (file)
@@ -1,6 +1,6 @@
 [root]
 name = "rusty-wam"
-version = "0.3.0"
+version = "0.3.5"
 dependencies = [
  "lalrpop 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lalrpop-util 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
index 81db725be7367a1c48bbac8707b4f024baa32e91..f79cd5aeb0db2f89a3e9ba1ec253942e83be105a 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "rusty-wam"
-version = "0.3.0"
+version = "0.3.5"
 authors = ["Mark Thom"]
 
 build = "build.rs"
index 63397a7ca12c889a00d4e1334caaf711c5117ba0..789e7e680ccd3f18934363f66ec3b016e93f6d68 100644 (file)
--- a/README.md
+++ b/README.md
@@ -16,70 +16,94 @@ syntax. No data types apart from atoms are currently supported.
 An example of the level of interaction currently supported is:
 
 ```
-l2> p(Z, Z).  
-l2> ?- p(Z, Z).  
-yes  
-l2> ?- p(Z, z).  
-yes  
-l2> ?- p(Z, w).  
-yes  
+l2> p(Z, Z).
+l2> ?- p(Z, Z).
+yes
+Z = _0
+l2> ?- p(Z, z).
+yes
+Z = z
+l2> ?- p(Z, w).
+yes
+Z = w
 l2> clouds(are, nice).
-l2> ?- p(z, w).  
-no  
-l2> ?- p(w, w).  
+l2> ?- p(z, w).
+no
+l2> ?- p(w, w).
 yes
 l2> ?- clouds(Z, Z).
 no
-l2> ?- clouds(Z, W).
-yes
 l2> ?- clouds(are, W).
 yes
+W = nice
 l2> ?- clouds(W, nice).
 yes
-l2> ?- clouds(nice, are).
+W = are
+l2> ?- p(Z, h(Z, W), f(W)).
+no
+l2> p(Z, h(Z, W), f(W)).
+l2> ?- p(z, h(z, z), f(w)).
 no
-l2> ?- p(Z, h(Z, W), f(W)).  
-no  
-l2> p(Z, h(Z, W), f(W)).  
-l2> ?- p(z, h(z, z), f(w)).  
-no  
-l2> ?- p(z, h(z, w), f(w)).  
-yes  
-l2> ?- p(Z, h(z, W), f(w)).  
-yes  
-l2> ?- p(z, h(Z, w), f(w)).  
+l2> ?- p(z, h(z, w), f(w)).
 yes
+l2> ?- p(z, h(z, W), f(w)).
+yes
+W = w
 l2> ?- p(Z, h(Z, w), f(Z)).
 yes
+Z = w
 l2> ?- p(z, h(Z, w), f(Z)).
 no
 l2> p(f(X), h(Y, f(a)), Y).
 l2> ?- p(Z, h(Z, W), f(W)).
 yes
+W = f(a)
+Z = f(f(a))
 l2> p(X, Y) :- q(X, Z), r(Z, Y).
 l2> q(q, s).
 l2> r(s, t).
 l2> ?- p(X, Y).
 yes
+Y = t
+X = q
 l2> ?- p(q, t).
 yes
 l2> ?- p(t, q).
 no
 l2> ?- p(q, T).
 yes
+T = t
 l2> ?- p(Q, t).
 yes
+Q = q
 l2> ?- p(t, t).
 no
+l2> p(X, Y) :- q(f(f(X)), R), r(S, T).
+l2> q(f(f(X)), r).
+l2> ?- p(X,  Y).
+yes
+X = _0
+Y = _1
+l2> p(X, Y) :- q(X, Y), r(X, Y).
+l2> q(s, t).
+l2> r(X, Y) :- r(a).
+l2> r(a).
+l2> ?- p(X, Y).
+yes
+X = s
+Y = t
+l2> ?- p(t, s).
+no
 l2> quit
 ```
 
 ## Occurs check
 
-There's no occurs check, so cyclic terms do unify:
+There's no occurs check, but there probably should be. Currently,
+attempting to unify on a cyclic term causes an infinite loop:
 
 ```
 l2> p(W, W).
 l2> ?- p(f(f(W)), W).
-yes
+*loops to infinity*
 ```
\ No newline at end of file
index bde5b35873e6070ae52ff58ab9d8ce4c72e2c404..f63ef55d92850380c0ef5f77f6d63f104c8f0930 100644 (file)
@@ -48,6 +48,19 @@ impl RegType {
     }
 }
 
+impl fmt::Display for VarReg {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            &VarReg::Norm(RegType::Perm(reg)) => write!(f, "Y{}", reg),
+            &VarReg::Norm(RegType::Temp(reg)) => write!(f, "X{}", reg),
+            &VarReg::ArgAndNorm(RegType::Perm(reg), arg) =>
+                write!(f, "Y{} A{}", reg, arg),
+            &VarReg::ArgAndNorm(RegType::Temp(reg), arg) =>
+                write!(f, "X{} A{}", reg, arg)
+        }
+    }
+}
+
 impl From<RegType> for Addr {
     fn from(reg: RegType) -> Addr {
         match reg {
@@ -78,6 +91,13 @@ impl VarReg {
             VarReg::ArgAndNorm(reg, _) | VarReg::Norm(reg) => reg
         }
     }
+
+    pub fn root_register(self) -> usize {
+        match self {
+            VarReg::ArgAndNorm(_, root) => root,
+            VarReg::Norm(root) => root.reg_num()
+        }
+    }
 }
 
 pub enum Term {
@@ -139,13 +159,46 @@ pub enum Addr {
     StackCell(usize),
 }
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
 pub enum HeapCellValue {
     NamedStr(usize, Atom),
     Ref(usize),
     Str(usize)
 }
 
+impl HeapCellValue {
+    pub fn as_ref(&self, focus: usize) -> HeapCellRef {
+        match self {
+            &HeapCellValue::Ref(r) => HeapCellRef::Ref(r),
+            &HeapCellValue::Str(s) => HeapCellRef::Str(s),
+            &HeapCellValue::NamedStr(_, _) => HeapCellRef::Str(focus)
+        }
+    }
+}
+
+#[derive(Copy, Clone)]
+pub enum HeapCellRef {
+    Ref(usize),
+    Str(usize)
+}
+
+impl HeapCellRef {
+    pub fn heap_offset(&self) -> usize {
+        match self {
+            &HeapCellRef::Ref(r) | &HeapCellRef::Str(r) => r
+        }
+    }        
+}
+
+impl From<HeapCellRef> for HeapCellValue {
+    fn from(hcr: HeapCellRef) -> HeapCellValue {
+        match hcr {
+            HeapCellRef::Ref(r) => HeapCellValue::Ref(r),
+            HeapCellRef::Str(s) => HeapCellValue::Str(s)
+        }
+    }
+}
+
 #[derive(Clone, Copy)]
 pub enum CodePtr {
     DirEntry(usize),
@@ -173,7 +226,7 @@ impl AddAssign<usize> for CodePtr {
 
 pub type Heap = Vec<HeapCellValue>;
 
-pub type Registers = Vec<HeapCellValue>;
+pub type Registers = Vec<HeapCellRef>;
 
 impl Term {
     pub fn subterms(&self) -> usize {
index 4754b744cad464f5eb37f312401cd1e0c2ef4a00..71ff300f645acd75669597938ab42a17a35df515 100644 (file)
@@ -259,6 +259,10 @@ impl<'a> CodeGenerator<'a> {
         CodeGenerator { marker: TermMarker::new() }
     }
 
+    pub fn vars(&self) -> &HashMap<&Var, VarReg> {
+        &self.marker.bindings
+    }
+
     fn to_structure<Target>(&mut self,
                             lvl: Level,
                             name: &'a Atom,
@@ -323,7 +327,7 @@ impl<'a> CodeGenerator<'a> {
         where Target: CompilationTarget<'a>
     {
         let iter       = Target::iter(term);
-        let mut target = Vec::<Target>::new();
+        let mut target = Vec::new();
 
         self.marker.advance(term);
 
@@ -412,7 +416,7 @@ impl<'a> CodeGenerator<'a> {
 
         body.append(&mut self.compile_query(p1));
 
-        let mut body = clauses.iter()
+        body = clauses.iter()
             .map(|ref term| self.compile_query(term))
             .fold(body, |mut body, ref mut cqs| {
                 body.append(cqs);
@@ -433,13 +437,18 @@ impl<'a> CodeGenerator<'a> {
     }
 
     pub fn compile_query(&mut self, term: &'a Term) -> Code {
-        let mut compiled_query =
-            vec![Line::Query(self.compile_target(term))];
-
-        if let &Term::Clause(_, ref atom, ref terms) = term {
-            let call = Line::Control(ControlInstruction::Call(atom.clone(),
-                                                              terms.len()));
-            compiled_query.push(call);
+        let mut compiled_query = vec![Line::Query(self.compile_target(term))];
+
+        match term {
+            &Term::Atom(_, ref atom) => {
+                let call = ControlInstruction::Call(atom.clone(), 0);
+                compiled_query.push(Line::Control(call));
+            },
+            &Term::Clause(_, ref atom, ref terms) => {
+                let call = ControlInstruction::Call(atom.clone(), terms.len());
+                compiled_query.push(Line::Control(call));
+            },
+            _ => {}
         }
 
         compiled_query
diff --git a/src/l2/heapview.rs b/src/l2/heapview.rs
new file mode 100644 (file)
index 0000000..15fa08c
--- /dev/null
@@ -0,0 +1,64 @@
+use l2::ast::*;
+
+use std::vec::Vec;
+
+#[derive(Clone, Copy)]
+pub enum HeapCellView<'a> {
+    Str(usize, &'a Atom),
+    Var(usize)
+}
+
+pub struct HeapCellViewer<'a> {
+    heap: &'a Heap,
+    state_stack: Vec<(usize, &'a HeapCellValue)>
+}
+
+impl<'a> HeapCellViewer<'a> {
+    pub fn new(heap: &'a Heap, focus: usize) -> Self {
+        HeapCellViewer {
+            heap: heap,
+            state_stack: vec![(focus, &heap[focus])]
+        }
+    }
+
+    fn follow(&self, value: &'a HeapCellValue) -> &'a HeapCellValue {
+        match value {
+            &HeapCellValue::NamedStr(_, _) => value,
+            &HeapCellValue::Ref(cell_num) | &HeapCellValue::Str(cell_num) =>
+                &self.heap[cell_num],
+        }
+    }
+}
+
+impl<'a> Iterator for HeapCellViewer<'a> {
+    type Item = HeapCellView<'a>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        while let Some(hcv) = self.state_stack.pop() {
+            match hcv {
+                (focus, &HeapCellValue::NamedStr(arity, ref name)) => {
+                    for i in (1 .. arity + 1).rev() {
+                        self.state_stack.push((focus + i, &self.heap[focus + i]));
+                    }                            
+                    
+                    return Some(HeapCellView::Str(arity, name));
+                },
+                (_, &HeapCellValue::Ref(cell_num)) => {
+                    let new_hcv = self.follow(hcv.1);
+
+                    if hcv.1 == new_hcv {
+                        return Some(HeapCellView::Var(cell_num));
+                    } else {
+                        self.state_stack.push((cell_num, new_hcv));
+                    }
+                },
+                (_, &HeapCellValue::Str(cell_num)) => {
+                    let new_hcv = self.follow(hcv.1);
+                    self.state_stack.push((cell_num, new_hcv));
+                }
+            }
+        }
+
+        None
+    }
+}
index 4bb84a7bdc81d1cd95bf4ef3d8271576c666e069..13ead93329722b9b8c79a8a4e58f51b571605c1a 100644 (file)
@@ -29,6 +29,9 @@ Clause : Term = {
 Rule : Rule = {
     <c:Clause> ":-" <h:Term> <cs: ("," <Term>)*> =>
          Rule { head: (c, h), clauses: cs },
+    <a:Atom> ":-" <h:Term> <cs: ("," <Term>)*> =>
+         Rule { head: (Term::Atom(Cell::new(RegType::Temp(0)), a), h),
+               clauses: cs }
 };
 
 Term : Term = {
index 6170071bc9f7db309e7c166346e7994e30bb39ef..dfddef99c7185e2cf08623a74b74fb2334b0eee3 100644 (file)
@@ -38,122 +38,130 @@ mod __parse__TopLevel {
         // State 0
         0, 0, 0, 0, 0, 8, 9, 10, 0,
         // State 1
-        11, 0, 0, -18, 0, 0, 0, 0, 0,
+        11, 0, 0, -20, 12, 0, 0, 0, 0,
         // State 2
-        0, 0, 0, -17, 12, 0, 0, 0, 0,
+        0, 0, 0, -19, 13, 0, 0, 0, 0,
         // State 3
-        0, 0, 0, 13, 0, 0, 0, 0, 0,
-        // State 4
         0, 0, 0, 14, 0, 0, 0, 0, 0,
+        // State 4
+        0, 0, 0, 15, 0, 0, 0, 0, 0,
         // State 5
         0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 6
-        0, 0, 0, -19, 0, 0, 0, 0, 0,
+        0, 0, 0, -21, 0, 0, 0, 0, 0,
         // State 7
-        0, 0, 0, 0, 0, 0, 9, 10, 0,
+        0, 0, 0, 0, 0, 0, 9, 19, 0,
         // State 8
-        0, 0, 0, -23, 0, 0, 0, 0, 0,
+        0, 0, 0, -25, 0, 0, 0, 0, 0,
         // State 9
-        -11, 0, 0, -11, 0, 0, 0, 0, 0,
+        -11, 0, 0, -11, -11, 0, 0, 0, 0,
         // State 10
-        0, 0, 0, 0, 0, 0, 24, 25, 0,
+        0, 0, 0, 0, 0, 0, 26, 27, 0,
         // State 11
-        0, 0, 0, 0, 0, 0, 30, 31, 0,
+        0, 0, 0, 0, 0, 0, 32, 33, 0,
         // State 12
-        0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 32, 33, 0,
         // State 13
         0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 14
-        32, 0, 0, -18, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 15
-        0, 0, 0, -17, 0, 0, 0, 0, 0,
+        35, 0, 0, -20, 0, 0, 0, 0, 0,
         // State 16
-        0, 0, 0, 33, 0, 0, 0, 0, 0,
+        0, 0, 0, -19, 0, 0, 0, 0, 0,
         // State 17
-        0, 0, 0, 0, 0, 0, 24, 25, 0,
+        0, 0, 0, 36, 0, 0, 0, 0, 0,
         // State 18
-        35, -18, -18, 0, 0, 0, 0, 0, 0,
+        -11, 0, 0, -11, 0, 0, 0, 0, 0,
         // State 19
-        0, 36, 37, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 26, 27, 0,
         // State 20
-        0, -17, -17, 0, 0, 0, 0, 0, 0,
+        38, -20, -20, 0, 0, 0, 0, 0, 0,
         // State 21
-        0, -12, -12, 0, 0, 0, 0, 0, 0,
+        0, 39, 40, 0, 0, 0, 0, 0, 0,
         // State 22
         0, -19, -19, 0, 0, 0, 0, 0, 0,
         // State 23
-        0, -23, -23, 0, 0, 0, 0, 0, 0,
+        0, -12, -12, 0, 0, 0, 0, 0, 0,
         // State 24
-        -11, -11, -11, 0, 0, 0, 0, 0, 0,
+        0, -21, -21, 0, 0, 0, 0, 0, 0,
         // State 25
-        38, 0, -18, -18, 0, 0, 0, 0, 0,
+        0, -25, -25, 0, 0, 0, 0, 0, 0,
         // State 26
-        0, 0, -17, -17, 0, 0, 0, 0, 0,
+        -11, -11, -11, 0, 0, 0, 0, 0, 0,
         // State 27
-        0, 0, 40, -15, 0, 0, 0, 0, 0,
+        41, 0, -20, -20, 0, 0, 0, 0, 0,
         // State 28
         0, 0, -19, -19, 0, 0, 0, 0, 0,
         // State 29
-        0, 0, -23, -23, 0, 0, 0, 0, 0,
+        0, 0, 43, -17, 0, 0, 0, 0, 0,
         // State 30
-        -11, 0, -11, -11, 0, 0, 0, 0, 0,
+        0, 0, -21, -21, 0, 0, 0, 0, 0,
         // State 31
-        0, 0, 0, 0, 0, 0, 24, 25, 0,
+        0, 0, -25, -25, 0, 0, 0, 0, 0,
         // State 32
-        0, 0, 0, 0, 0, 0, 0, 0, 0,
+        -11, 0, -11, -11, 0, 0, 0, 0, 0,
         // State 33
-        0, 43, 44, 0, 0, 0, 0, 0, 0,
+        0, 0, 43, -15, 0, 0, 0, 0, 0,
         // State 34
-        0, 0, 0, 0, 0, 0, 24, 25, 0,
+        0, 0, 0, 0, 0, 0, 26, 27, 0,
         // State 35
-        0, 0, 0, -13, -13, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 36
-        0, 0, 0, 0, 0, 0, -9, -9, 0,
+        0, 47, 48, 0, 0, 0, 0, 0, 0,
         // State 37
-        0, 0, 0, 0, 0, 0, 24, 25, 0,
+        0, 0, 0, 0, 0, 0, 26, 27, 0,
         // State 38
-        0, 0, 49, -16, 0, 0, 0, 0, 0,
+        0, 0, 0, -13, -13, 0, 0, 0, 0,
         // State 39
-        0, 0, 0, 0, 0, 0, 30, 31, 0,
+        0, 0, 0, 0, 0, 0, -9, -9, 0,
         // State 40
-        0, 0, 0, 0, 0, 0, 24, 25, 0,
+        0, 0, 0, 0, 0, 0, 26, 27, 0,
         // State 41
-        0, 52, 37, 0, 0, 0, 0, 0, 0,
+        0, 0, 53, -18, 0, 0, 0, 0, 0,
         // State 42
-        0, 0, 0, -14, -14, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 32, 33, 0,
         // State 43
-        0, 0, 0, 0, 0, 0, -10, -10, 0,
+        0, 0, 53, -16, 0, 0, 0, 0, 0,
         // State 44
-        0, 0, 0, 0, 0, 0, 24, 25, 0,
+        0, 0, 0, 0, 0, 0, 26, 27, 0,
         // State 45
-        0, 54, 37, 0, 0, 0, 0, 0, 0,
+        0, 56, 40, 0, 0, 0, 0, 0, 0,
         // State 46
-        0, 0, 0, 0, 0, 0, 24, 25, 0,
+        0, 0, 0, -14, -14, 0, 0, 0, 0,
         // State 47
-        0, 56, 37, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, -10, -10, 0,
         // State 48
-        0, 0, 0, 0, 0, 0, 30, 31, 0,
+        0, 0, 0, 0, 0, 0, 26, 27, 0,
         // State 49
-        0, 0, -4, -4, 0, 0, 0, 0, 0,
+        0, 58, 40, 0, 0, 0, 0, 0, 0,
         // State 50
-        0, 58, 44, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 26, 27, 0,
         // State 51
-        0, 0, 0, -13, 0, 0, 0, 0, 0,
+        0, 60, 40, 0, 0, 0, 0, 0, 0,
         // State 52
-        0, 59, 44, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 32, 33, 0,
         // State 53
-        0, -13, -13, 0, 0, 0, 0, 0, 0,
+        0, 0, -4, -4, 0, 0, 0, 0, 0,
         // State 54
-        0, 60, 44, 0, 0, 0, 0, 0, 0,
+        0, 62, 48, 0, 0, 0, 0, 0, 0,
         // State 55
-        0, 0, -13, -13, 0, 0, 0, 0, 0,
+        0, 0, 0, -13, 0, 0, 0, 0, 0,
         // State 56
-        0, 0, -5, -5, 0, 0, 0, 0, 0,
+        0, 63, 48, 0, 0, 0, 0, 0, 0,
         // State 57
-        0, 0, 0, -14, 0, 0, 0, 0, 0,
+        0, -13, -13, 0, 0, 0, 0, 0, 0,
         // State 58
-        0, -14, -14, 0, 0, 0, 0, 0, 0,
+        0, 64, 48, 0, 0, 0, 0, 0, 0,
         // State 59
+        0, 0, -13, -13, 0, 0, 0, 0, 0,
+        // State 60
+        0, 0, -5, -5, 0, 0, 0, 0, 0,
+        // State 61
+        0, 0, 0, -14, 0, 0, 0, 0, 0,
+        // State 62
+        0, -14, -14, 0, 0, 0, 0, 0, 0,
+        // State 63
         0, 0, -14, -14, 0, 0, 0, 0, 0,
     ];
     const __EOF_ACTION: &'static [i32] = &[
@@ -162,16 +170,16 @@ mod __parse__TopLevel {
         0,
         0,
         0,
-        -24,
+        -26,
         0,
         0,
         0,
         0,
         0,
         0,
-        -21,
-        -22,
         0,
+        -23,
+        -24,
         0,
         0,
         0,
@@ -189,7 +197,11 @@ mod __parse__TopLevel {
         0,
         0,
         0,
-        -20,
+        0,
+        0,
+        0,
+        -22,
+        0,
         0,
         0,
         0,
@@ -234,17 +246,17 @@ mod __parse__TopLevel {
         // State 6
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 7
-        0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 17, 0, 7, 0,
+        0, 0, 0, 0, 0, 0, 16, 0, 17, 0, 18, 0, 7, 0,
         // State 8
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 9
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 10
-        0, 0, 0, 0, 0, 18, 19, 20, 21, 0, 22, 0, 23, 0,
+        0, 0, 0, 0, 0, 20, 21, 22, 23, 0, 24, 0, 25, 0,
         // State 11
-        0, 0, 0, 0, 0, 0, 26, 0, 27, 0, 28, 0, 29, 0,
+        0, 0, 0, 0, 0, 0, 28, 0, 29, 0, 30, 0, 31, 0,
         // State 12
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 28, 0, 29, 0, 34, 0, 31, 0,
         // State 13
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 14
@@ -254,11 +266,11 @@ mod __parse__TopLevel {
         // State 16
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 17
-        0, 0, 0, 0, 0, 0, 19, 34, 21, 0, 22, 0, 23, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 18
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 19
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 21, 37, 23, 0, 24, 0, 25, 0,
         // State 20
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 21
@@ -274,57 +286,57 @@ mod __parse__TopLevel {
         // State 26
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 27
-        0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 28
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 29
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 30
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 31
-        0, 0, 0, 0, 0, 41, 19, 42, 21, 0, 22, 0, 23, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 32
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 33
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 34
-        0, 0, 0, 0, 0, 45, 19, 46, 21, 0, 22, 0, 23, 0,
+        0, 0, 0, 0, 0, 45, 21, 46, 23, 0, 24, 0, 25, 0,
         // State 35
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 36
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 37
-        0, 0, 0, 0, 0, 47, 19, 48, 21, 0, 22, 0, 23, 0,
+        0, 0, 0, 0, 0, 49, 21, 50, 23, 0, 24, 0, 25, 0,
         // State 38
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 39
-        0, 0, 0, 0, 0, 0, 26, 0, 27, 0, 50, 0, 29, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 40
-        0, 0, 0, 0, 0, 0, 19, 51, 21, 0, 22, 0, 23, 0,
+        0, 0, 0, 0, 0, 51, 21, 52, 23, 0, 24, 0, 25, 0,
         // State 41
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 42
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 28, 0, 29, 0, 54, 0, 31, 0,
         // State 43
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 44
-        0, 0, 0, 0, 0, 0, 19, 53, 21, 0, 22, 0, 23, 0,
+        0, 0, 0, 0, 0, 0, 21, 55, 23, 0, 24, 0, 25, 0,
         // State 45
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 46
-        0, 0, 0, 0, 0, 0, 19, 55, 21, 0, 22, 0, 23, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 47
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 48
-        0, 0, 0, 0, 0, 0, 26, 0, 27, 0, 57, 0, 29, 0,
+        0, 0, 0, 0, 0, 0, 21, 57, 23, 0, 24, 0, 25, 0,
         // State 49
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 50
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 21, 59, 23, 0, 24, 0, 25, 0,
         // State 51
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 52
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 28, 0, 29, 0, 61, 0, 31, 0,
         // State 53
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 54
@@ -339,6 +351,14 @@ mod __parse__TopLevel {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         // State 59
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        // State 60
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        // State 61
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        // State 62
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        // State 63
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     ];
     fn __expected_tokens(__state: usize) -> Vec<::std::string::String> {
         const __TERMINAL: &'static [&'static str] = &[
@@ -482,116 +502,116 @@ mod __parse__TopLevel {
     {
         let __nonterminal = match -__action {
             1 => {
-                // ("," <Term>) = ",", Term => ActionFn(14);
+                // ("," <Term>) = ",", Term => ActionFn(15);
                 let __sym1 = __pop_NtTerm(__symbols);
                 let __sym0 = __pop_Term_22_2c_22(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym1.2.clone();
-                let __nt = super::__action14::<>(input, __sym0, __sym1);
+                let __nt = super::__action15::<>(input, __sym0, __sym1);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 2);
                 __symbols.push((__start, __Symbol::Nt_28_22_2c_22_20_3cTerm_3e_29(__nt), __end));
                 0
             }
             2 => {
-                // ("," <Term>)* =  => ActionFn(12);
+                // ("," <Term>)* =  => ActionFn(13);
                 let __start = __symbols.last().map(|s| s.2.clone()).unwrap_or_default();
                 let __end = __lookahead_start.cloned().unwrap_or_else(|| __start.clone());
-                let __nt = super::__action12::<>(input, &__start, &__end);
+                let __nt = super::__action13::<>(input, &__start, &__end);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 0);
                 __symbols.push((__start, __Symbol::Nt_28_22_2c_22_20_3cTerm_3e_29_2a(__nt), __end));
                 1
             }
             3 => {
-                // ("," <Term>)* = ("," <Term>)+ => ActionFn(13);
+                // ("," <Term>)* = ("," <Term>)+ => ActionFn(14);
                 let __sym0 = __pop_Nt_28_22_2c_22_20_3cTerm_3e_29_2b(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym0.2.clone();
-                let __nt = super::__action13::<>(input, __sym0);
+                let __nt = super::__action14::<>(input, __sym0);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 1);
                 __symbols.push((__start, __Symbol::Nt_28_22_2c_22_20_3cTerm_3e_29_2a(__nt), __end));
                 1
             }
             4 => {
-                // ("," <Term>)+ = ",", Term => ActionFn(22);
+                // ("," <Term>)+ = ",", Term => ActionFn(23);
                 let __sym1 = __pop_NtTerm(__symbols);
                 let __sym0 = __pop_Term_22_2c_22(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym1.2.clone();
-                let __nt = super::__action22::<>(input, __sym0, __sym1);
+                let __nt = super::__action23::<>(input, __sym0, __sym1);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 2);
                 __symbols.push((__start, __Symbol::Nt_28_22_2c_22_20_3cTerm_3e_29_2b(__nt), __end));
                 2
             }
             5 => {
-                // ("," <Term>)+ = ("," <Term>)+, ",", Term => ActionFn(23);
+                // ("," <Term>)+ = ("," <Term>)+, ",", Term => ActionFn(24);
                 let __sym2 = __pop_NtTerm(__symbols);
                 let __sym1 = __pop_Term_22_2c_22(__symbols);
                 let __sym0 = __pop_Nt_28_22_2c_22_20_3cTerm_3e_29_2b(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym2.2.clone();
-                let __nt = super::__action23::<>(input, __sym0, __sym1, __sym2);
+                let __nt = super::__action24::<>(input, __sym0, __sym1, __sym2);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 3);
                 __symbols.push((__start, __Symbol::Nt_28_22_2c_22_20_3cTerm_3e_29_2b(__nt), __end));
                 2
             }
             6 => {
-                // (<BoxedTerm> ",") = BoxedTerm, "," => ActionFn(17);
+                // (<BoxedTerm> ",") = BoxedTerm, "," => ActionFn(18);
                 let __sym1 = __pop_Term_22_2c_22(__symbols);
                 let __sym0 = __pop_NtBoxedTerm(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym1.2.clone();
-                let __nt = super::__action17::<>(input, __sym0, __sym1);
+                let __nt = super::__action18::<>(input, __sym0, __sym1);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 2);
                 __symbols.push((__start, __Symbol::Nt_28_3cBoxedTerm_3e_20_22_2c_22_29(__nt), __end));
                 3
             }
             7 => {
-                // (<BoxedTerm> ",")* =  => ActionFn(15);
+                // (<BoxedTerm> ",")* =  => ActionFn(16);
                 let __start = __symbols.last().map(|s| s.2.clone()).unwrap_or_default();
                 let __end = __lookahead_start.cloned().unwrap_or_else(|| __start.clone());
-                let __nt = super::__action15::<>(input, &__start, &__end);
+                let __nt = super::__action16::<>(input, &__start, &__end);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 0);
                 __symbols.push((__start, __Symbol::Nt_28_3cBoxedTerm_3e_20_22_2c_22_29_2a(__nt), __end));
                 4
             }
             8 => {
-                // (<BoxedTerm> ",")* = (<BoxedTerm> ",")+ => ActionFn(16);
+                // (<BoxedTerm> ",")* = (<BoxedTerm> ",")+ => ActionFn(17);
                 let __sym0 = __pop_Nt_28_3cBoxedTerm_3e_20_22_2c_22_29_2b(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym0.2.clone();
-                let __nt = super::__action16::<>(input, __sym0);
+                let __nt = super::__action17::<>(input, __sym0);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 1);
                 __symbols.push((__start, __Symbol::Nt_28_3cBoxedTerm_3e_20_22_2c_22_29_2a(__nt), __end));
                 4
             }
             9 => {
-                // (<BoxedTerm> ",")+ = BoxedTerm, "," => ActionFn(26);
+                // (<BoxedTerm> ",")+ = BoxedTerm, "," => ActionFn(29);
                 let __sym1 = __pop_Term_22_2c_22(__symbols);
                 let __sym0 = __pop_NtBoxedTerm(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym1.2.clone();
-                let __nt = super::__action26::<>(input, __sym0, __sym1);
+                let __nt = super::__action29::<>(input, __sym0, __sym1);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 2);
                 __symbols.push((__start, __Symbol::Nt_28_3cBoxedTerm_3e_20_22_2c_22_29_2b(__nt), __end));
                 5
             }
             10 => {
-                // (<BoxedTerm> ",")+ = (<BoxedTerm> ",")+, BoxedTerm, "," => ActionFn(27);
+                // (<BoxedTerm> ",")+ = (<BoxedTerm> ",")+, BoxedTerm, "," => ActionFn(30);
                 let __sym2 = __pop_Term_22_2c_22(__symbols);
                 let __sym1 = __pop_NtBoxedTerm(__symbols);
                 let __sym0 = __pop_Nt_28_3cBoxedTerm_3e_20_22_2c_22_29_2b(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym2.2.clone();
-                let __nt = super::__action27::<>(input, __sym0, __sym1, __sym2);
+                let __nt = super::__action30::<>(input, __sym0, __sym1, __sym2);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 3);
                 __symbols.push((__start, __Symbol::Nt_28_3cBoxedTerm_3e_20_22_2c_22_29_2b(__nt), __end));
@@ -620,21 +640,21 @@ mod __parse__TopLevel {
                 7
             }
             13 => {
-                // Clause = Atom, "(", BoxedTerm, ")" => ActionFn(28);
+                // Clause = Atom, "(", BoxedTerm, ")" => ActionFn(31);
                 let __sym3 = __pop_Term_22_29_22(__symbols);
                 let __sym2 = __pop_NtBoxedTerm(__symbols);
                 let __sym1 = __pop_Term_22_28_22(__symbols);
                 let __sym0 = __pop_NtAtom(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym3.2.clone();
-                let __nt = super::__action28::<>(input, __sym0, __sym1, __sym2, __sym3);
+                let __nt = super::__action31::<>(input, __sym0, __sym1, __sym2, __sym3);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 4);
                 __symbols.push((__start, __Symbol::NtClause(__nt), __end));
                 8
             }
             14 => {
-                // Clause = Atom, "(", (<BoxedTerm> ",")+, BoxedTerm, ")" => ActionFn(29);
+                // Clause = Atom, "(", (<BoxedTerm> ",")+, BoxedTerm, ")" => ActionFn(32);
                 let __sym4 = __pop_Term_22_29_22(__symbols);
                 let __sym3 = __pop_NtBoxedTerm(__symbols);
                 let __sym2 = __pop_Nt_28_3cBoxedTerm_3e_20_22_2c_22_29_2b(__symbols);
@@ -642,73 +662,100 @@ mod __parse__TopLevel {
                 let __sym0 = __pop_NtAtom(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym4.2.clone();
-                let __nt = super::__action29::<>(input, __sym0, __sym1, __sym2, __sym3, __sym4);
+                let __nt = super::__action32::<>(input, __sym0, __sym1, __sym2, __sym3, __sym4);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 5);
                 __symbols.push((__start, __Symbol::NtClause(__nt), __end));
                 8
             }
             15 => {
-                // Rule = Clause, ":-", Term => ActionFn(24);
+                // Rule = Clause, ":-", Term => ActionFn(25);
                 let __sym2 = __pop_NtTerm(__symbols);
                 let __sym1 = __pop_Term_22_3a_2d_22(__symbols);
                 let __sym0 = __pop_NtClause(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym2.2.clone();
-                let __nt = super::__action24::<>(input, __sym0, __sym1, __sym2);
+                let __nt = super::__action25::<>(input, __sym0, __sym1, __sym2);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 3);
                 __symbols.push((__start, __Symbol::NtRule(__nt), __end));
                 9
             }
             16 => {
-                // Rule = Clause, ":-", Term, ("," <Term>)+ => ActionFn(25);
+                // Rule = Clause, ":-", Term, ("," <Term>)+ => ActionFn(26);
                 let __sym3 = __pop_Nt_28_22_2c_22_20_3cTerm_3e_29_2b(__symbols);
                 let __sym2 = __pop_NtTerm(__symbols);
                 let __sym1 = __pop_Term_22_3a_2d_22(__symbols);
                 let __sym0 = __pop_NtClause(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym3.2.clone();
-                let __nt = super::__action25::<>(input, __sym0, __sym1, __sym2, __sym3);
+                let __nt = super::__action26::<>(input, __sym0, __sym1, __sym2, __sym3);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 4);
                 __symbols.push((__start, __Symbol::NtRule(__nt), __end));
                 9
             }
             17 => {
-                // Term = Clause => ActionFn(8);
+                // Rule = Atom, ":-", Term => ActionFn(27);
+                let __sym2 = __pop_NtTerm(__symbols);
+                let __sym1 = __pop_Term_22_3a_2d_22(__symbols);
+                let __sym0 = __pop_NtAtom(__symbols);
+                let __start = __sym0.0.clone();
+                let __end = __sym2.2.clone();
+                let __nt = super::__action27::<>(input, __sym0, __sym1, __sym2);
+                let __states_len = __states.len();
+                __states.truncate(__states_len - 3);
+                __symbols.push((__start, __Symbol::NtRule(__nt), __end));
+                9
+            }
+            18 => {
+                // Rule = Atom, ":-", Term, ("," <Term>)+ => ActionFn(28);
+                let __sym3 = __pop_Nt_28_22_2c_22_20_3cTerm_3e_29_2b(__symbols);
+                let __sym2 = __pop_NtTerm(__symbols);
+                let __sym1 = __pop_Term_22_3a_2d_22(__symbols);
+                let __sym0 = __pop_NtAtom(__symbols);
+                let __start = __sym0.0.clone();
+                let __end = __sym3.2.clone();
+                let __nt = super::__action28::<>(input, __sym0, __sym1, __sym2, __sym3);
+                let __states_len = __states.len();
+                __states.truncate(__states_len - 4);
+                __symbols.push((__start, __Symbol::NtRule(__nt), __end));
+                9
+            }
+            19 => {
+                // Term = Clause => ActionFn(9);
                 let __sym0 = __pop_NtClause(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym0.2.clone();
-                let __nt = super::__action8::<>(input, __sym0);
+                let __nt = super::__action9::<>(input, __sym0);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 1);
                 __symbols.push((__start, __Symbol::NtTerm(__nt), __end));
                 10
             }
-            18 => {
-                // Term = Atom => ActionFn(9);
+            20 => {
+                // Term = Atom => ActionFn(10);
                 let __sym0 = __pop_NtAtom(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym0.2.clone();
-                let __nt = super::__action9::<>(input, __sym0);
+                let __nt = super::__action10::<>(input, __sym0);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 1);
                 __symbols.push((__start, __Symbol::NtTerm(__nt), __end));
                 10
             }
-            19 => {
-                // Term = Var => ActionFn(10);
+            21 => {
+                // Term = Var => ActionFn(11);
                 let __sym0 = __pop_NtVar(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym0.2.clone();
-                let __nt = super::__action10::<>(input, __sym0);
+                let __nt = super::__action11::<>(input, __sym0);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 1);
                 __symbols.push((__start, __Symbol::NtTerm(__nt), __end));
                 10
             }
-            20 => {
+            22 => {
                 // TopLevel = "?-", Term, "." => ActionFn(1);
                 let __sym2 = __pop_Term_22_2e_22(__symbols);
                 let __sym1 = __pop_NtTerm(__symbols);
@@ -721,7 +768,7 @@ mod __parse__TopLevel {
                 __symbols.push((__start, __Symbol::NtTopLevel(__nt), __end));
                 11
             }
-            21 => {
+            23 => {
                 // TopLevel = Rule, "." => ActionFn(2);
                 let __sym1 = __pop_Term_22_2e_22(__symbols);
                 let __sym0 = __pop_NtRule(__symbols);
@@ -733,7 +780,7 @@ mod __parse__TopLevel {
                 __symbols.push((__start, __Symbol::NtTopLevel(__nt), __end));
                 11
             }
-            22 => {
+            24 => {
                 // TopLevel = Term, "." => ActionFn(3);
                 let __sym1 = __pop_Term_22_2e_22(__symbols);
                 let __sym0 = __pop_NtTerm(__symbols);
@@ -745,18 +792,18 @@ mod __parse__TopLevel {
                 __symbols.push((__start, __Symbol::NtTopLevel(__nt), __end));
                 11
             }
-            23 => {
-                // Var = r#"[A-Z][a-z0-9_]*"# => ActionFn(11);
+            25 => {
+                // Var = r#"[A-Z][a-z0-9_]*"# => ActionFn(12);
                 let __sym0 = __pop_Termr_23_22_5bA_2dZ_5d_5ba_2dz0_2d9___5d_2a_22_23(__symbols);
                 let __start = __sym0.0.clone();
                 let __end = __sym0.2.clone();
-                let __nt = super::__action11::<>(input, __sym0);
+                let __nt = super::__action12::<>(input, __sym0);
                 let __states_len = __states.len();
                 __states.truncate(__states_len - 1);
                 __symbols.push((__start, __Symbol::NtVar(__nt), __end));
                 12
             }
-            24 => {
+            26 => {
                 // __TopLevel = TopLevel => ActionFn(0);
                 let __sym0 = __pop_NtTopLevel(__symbols);
                 let __start = __sym0.0.clone();
@@ -1383,6 +1430,21 @@ pub fn __action7<
 #[allow(unused_variables)]
 pub fn __action8<
     'input,
+>(
+    input: &'input str,
+    (_, a, _): (usize, Atom, usize),
+    (_, _, _): (usize, &'input str, usize),
+    (_, h, _): (usize, Term, usize),
+    (_, cs, _): (usize, ::std::vec::Vec<Term>, usize),
+) -> Rule
+{
+    Rule { head: (Term::Atom(Cell::new(RegType::Temp(0)), a), h),
+               clauses: cs }
+}
+
+#[allow(unused_variables)]
+pub fn __action9<
+    'input,
 >(
     input: &'input str,
     (_, __0, _): (usize, Term, usize),
@@ -1392,7 +1454,7 @@ pub fn __action8<
 }
 
 #[allow(unused_variables)]
-pub fn __action9<
+pub fn __action10<
     'input,
 >(
     input: &'input str,
@@ -1403,7 +1465,7 @@ pub fn __action9<
 }
 
 #[allow(unused_variables)]
-pub fn __action10<
+pub fn __action11<
     'input,
 >(
     input: &'input str,
@@ -1414,7 +1476,7 @@ pub fn __action10<
 }
 
 #[allow(unused_variables)]
-pub fn __action11<
+pub fn __action12<
     'input,
 >(
     input: &'input str,
@@ -1425,7 +1487,7 @@ pub fn __action11<
 }
 
 #[allow(unused_variables)]
-pub fn __action12<
+pub fn __action13<
     'input,
 >(
     input: &'input str,
@@ -1437,7 +1499,7 @@ pub fn __action12<
 }
 
 #[allow(unused_variables)]
-pub fn __action13<
+pub fn __action14<
     'input,
 >(
     input: &'input str,
@@ -1448,7 +1510,7 @@ pub fn __action13<
 }
 
 #[allow(unused_variables)]
-pub fn __action14<
+pub fn __action15<
     'input,
 >(
     input: &'input str,
@@ -1460,7 +1522,7 @@ pub fn __action14<
 }
 
 #[allow(unused_variables)]
-pub fn __action15<
+pub fn __action16<
     'input,
 >(
     input: &'input str,
@@ -1472,7 +1534,7 @@ pub fn __action15<
 }
 
 #[allow(unused_variables)]
-pub fn __action16<
+pub fn __action17<
     'input,
 >(
     input: &'input str,
@@ -1483,7 +1545,7 @@ pub fn __action16<
 }
 
 #[allow(unused_variables)]
-pub fn __action17<
+pub fn __action18<
     'input,
 >(
     input: &'input str,
@@ -1495,7 +1557,7 @@ pub fn __action17<
 }
 
 #[allow(unused_variables)]
-pub fn __action18<
+pub fn __action19<
     'input,
 >(
     input: &'input str,
@@ -1506,7 +1568,7 @@ pub fn __action18<
 }
 
 #[allow(unused_variables)]
-pub fn __action19<
+pub fn __action20<
     'input,
 >(
     input: &'input str,
@@ -1518,7 +1580,7 @@ pub fn __action19<
 }
 
 #[allow(unused_variables)]
-pub fn __action20<
+pub fn __action21<
     'input,
 >(
     input: &'input str,
@@ -1529,7 +1591,7 @@ pub fn __action20<
 }
 
 #[allow(unused_variables)]
-pub fn __action21<
+pub fn __action22<
     'input,
 >(
     input: &'input str,
@@ -1541,7 +1603,7 @@ pub fn __action21<
 }
 
 #[allow(unused_variables)]
-pub fn __action22<
+pub fn __action23<
     'input,
 >(
     input: &'input str,
@@ -1551,20 +1613,20 @@ pub fn __action22<
 {
     let __start0 = __0.0.clone();
     let __end0 = __1.2.clone();
-    let __temp0 = __action14(
+    let __temp0 = __action15(
         input,
         __0,
         __1,
     );
     let __temp0 = (__start0, __temp0, __end0);
-    __action20(
+    __action21(
         input,
         __temp0,
     )
 }
 
 #[allow(unused_variables)]
-pub fn __action23<
+pub fn __action24<
     'input,
 >(
     input: &'input str,
@@ -1575,13 +1637,13 @@ pub fn __action23<
 {
     let __start0 = __1.0.clone();
     let __end0 = __2.2.clone();
-    let __temp0 = __action14(
+    let __temp0 = __action15(
         input,
         __1,
         __2,
     );
     let __temp0 = (__start0, __temp0, __end0);
-    __action21(
+    __action22(
         input,
         __0,
         __temp0,
@@ -1589,7 +1651,7 @@ pub fn __action23<
 }
 
 #[allow(unused_variables)]
-pub fn __action24<
+pub fn __action25<
     'input,
 >(
     input: &'input str,
@@ -1600,7 +1662,7 @@ pub fn __action24<
 {
     let __start0 = __2.2.clone();
     let __end0 = __2.2.clone();
-    let __temp0 = __action12(
+    let __temp0 = __action13(
         input,
         &__start0,
         &__end0,
@@ -1616,7 +1678,7 @@ pub fn __action24<
 }
 
 #[allow(unused_variables)]
-pub fn __action25<
+pub fn __action26<
     'input,
 >(
     input: &'input str,
@@ -1628,7 +1690,7 @@ pub fn __action25<
 {
     let __start0 = __3.0.clone();
     let __end0 = __3.2.clone();
-    let __temp0 = __action13(
+    let __temp0 = __action14(
         input,
         __3,
     );
@@ -1643,7 +1705,61 @@ pub fn __action25<
 }
 
 #[allow(unused_variables)]
-pub fn __action26<
+pub fn __action27<
+    'input,
+>(
+    input: &'input str,
+    __0: (usize, Atom, usize),
+    __1: (usize, &'input str, usize),
+    __2: (usize, Term, usize),
+) -> Rule
+{
+    let __start0 = __2.2.clone();
+    let __end0 = __2.2.clone();
+    let __temp0 = __action13(
+        input,
+        &__start0,
+        &__end0,
+    );
+    let __temp0 = (__start0, __temp0, __end0);
+    __action8(
+        input,
+        __0,
+        __1,
+        __2,
+        __temp0,
+    )
+}
+
+#[allow(unused_variables)]
+pub fn __action28<
+    'input,
+>(
+    input: &'input str,
+    __0: (usize, Atom, usize),
+    __1: (usize, &'input str, usize),
+    __2: (usize, Term, usize),
+    __3: (usize, ::std::vec::Vec<Term>, usize),
+) -> Rule
+{
+    let __start0 = __3.0.clone();
+    let __end0 = __3.2.clone();
+    let __temp0 = __action14(
+        input,
+        __3,
+    );
+    let __temp0 = (__start0, __temp0, __end0);
+    __action8(
+        input,
+        __0,
+        __1,
+        __2,
+        __temp0,
+    )
+}
+
+#[allow(unused_variables)]
+pub fn __action29<
     'input,
 >(
     input: &'input str,
@@ -1653,20 +1769,20 @@ pub fn __action26<
 {
     let __start0 = __0.0.clone();
     let __end0 = __1.2.clone();
-    let __temp0 = __action17(
+    let __temp0 = __action18(
         input,
         __0,
         __1,
     );
     let __temp0 = (__start0, __temp0, __end0);
-    __action18(
+    __action19(
         input,
         __temp0,
     )
 }
 
 #[allow(unused_variables)]
-pub fn __action27<
+pub fn __action30<
     'input,
 >(
     input: &'input str,
@@ -1677,13 +1793,13 @@ pub fn __action27<
 {
     let __start0 = __1.0.clone();
     let __end0 = __2.2.clone();
-    let __temp0 = __action17(
+    let __temp0 = __action18(
         input,
         __1,
         __2,
     );
     let __temp0 = (__start0, __temp0, __end0);
-    __action19(
+    __action20(
         input,
         __0,
         __temp0,
@@ -1691,7 +1807,7 @@ pub fn __action27<
 }
 
 #[allow(unused_variables)]
-pub fn __action28<
+pub fn __action31<
     'input,
 >(
     input: &'input str,
@@ -1703,7 +1819,7 @@ pub fn __action28<
 {
     let __start0 = __1.2.clone();
     let __end0 = __2.0.clone();
-    let __temp0 = __action15(
+    let __temp0 = __action16(
         input,
         &__start0,
         &__end0,
@@ -1720,7 +1836,7 @@ pub fn __action28<
 }
 
 #[allow(unused_variables)]
-pub fn __action29<
+pub fn __action32<
     'input,
 >(
     input: &'input str,
@@ -1733,7 +1849,7 @@ pub fn __action29<
 {
     let __start0 = __2.0.clone();
     let __end0 = __2.2.clone();
-    let __temp0 = __action16(
+    let __temp0 = __action17(
         input,
         __2,
     );
index 2d95d642faa530bf23953b0ad0226b369c34876e..50feb0a99f779283e91e09447381d9a4c10520ae 100644 (file)
@@ -1,8 +1,9 @@
 use l2::ast::*;
+use l2::codegen::*;
+use l2::heapview::*;
 use l2::stack::*;
 
 use std::collections::HashMap;
-use std::ops::{Index, IndexMut};
 use std::vec::Vec;
 
 #[derive(Clone, Copy)]
@@ -31,28 +32,6 @@ pub struct Machine {
     code_dir: CodeDir
 }
 
-impl Index<Addr> for MachineState {
-    type Output = HeapCellValue;
-
-    fn index(&self, index: Addr) -> &Self::Output {
-        match index {
-            Addr::HeapCell(hc)  => &self.heap[hc],
-            Addr::RegNum(reg)   => &self.registers[reg],
-            Addr::StackCell(sc) => &self.stack[sc]
-        }
-    }
-}
-
-impl IndexMut<Addr> for MachineState {
-    fn index_mut(&mut self, index: Addr) -> &mut Self::Output {
-        match index {
-            Addr::HeapCell(hc)  => &mut self.heap[hc],
-            Addr::RegNum(reg)   => &mut self.registers[reg],
-            Addr::StackCell(sc) => &mut self.stack[sc]
-        }
-    }
-}
-
 impl Machine {
     pub fn new() -> Self {
         Machine {
@@ -104,11 +83,11 @@ impl Machine {
                 &Line::Control(ref control_instr) =>
                     self.ms.execute_ctrl_instr(&self.code_dir, control_instr),
             }
-            
+
             if self.failed() {
                 return false;
             }
-            
+
             match self.ms.p {
                 CodePtr::DirEntry(p) if p < self.code.len() =>
                     instr = &self.code[p],
@@ -119,18 +98,91 @@ impl Machine {
         true
     }
 
-    pub fn execute_query(&mut self, query: Code) -> bool {
+    fn heap_view(&self, var_dir: HashMap<&Var, HeapCellRef>) -> String {
+        let mut result = String::new();
+
+        for (var, hcr) in var_dir {
+            let mut arities = Vec::new();
+
+            let viewer = HeapCellViewer::new(&self.ms.heap, hcr.heap_offset());
+
+            if result != "" {
+                result += "\n";
+            }
+
+            result += var.as_str();
+            result += " = ";
+
+            for view in viewer {
+                match arities.pop() {
+                    Some(n) => arities.push(n-1),
+                    None => {}
+                }
+
+                if !(arities.is_empty() || result.ends_with("(")) {
+                    result += ", ";
+                }
+
+                match view {
+                    HeapCellView::Str(arity, ref name) => {
+                        result += name.as_str();
+
+                        if arity > 0 {
+                            arities.push(arity);
+                            result += "(";
+                        }
+                    },
+                    HeapCellView::Var(cell_num) => {
+                        result += "_";
+                        result += cell_num.to_string().as_str();
+                    }
+                }
+
+                while let Some(&0) = arities.last() {
+                    result += ")";
+                    arities.pop();
+                }
+            }
+        }
+
+        result
+    }
+
+    pub fn run_query(&mut self, code: Code, cg: &CodeGenerator) -> Option<String>
+    {
         let mut succeeded = true;
-        
-        for instr in query {
+
+        for instr in code.iter().take(1) {
             succeeded = self.execute_instr(&instr);
-            if !succeeded {
-                break;
-            }
         }
 
-        self.ms.reset();
-        succeeded
+        if succeeded {
+            let mut heap_locs = HashMap::new();
+
+            for (var, vr) in cg.vars() {
+                let hcr = self.ms.registers[vr.root_register()];
+                heap_locs.insert(*var, hcr);
+            }
+
+            for instr in code.iter().skip(1) {
+                succeeded = self.execute_instr(&instr);
+                if !succeeded {
+                    break;
+                }
+            }
+
+            if succeeded {
+                let result = Some(self.heap_view(heap_locs));
+                self.ms.reset();
+                result
+            } else {
+                self.ms.reset();
+                None
+            }
+        } else {
+            self.ms.reset();
+            None
+        }
     }
 }
 
@@ -144,14 +196,29 @@ impl MachineState {
                        heap: Vec::with_capacity(256),
                        mode: MachineMode::Write,
                        stack: Stack::new(),
-                       registers: vec![HeapCellValue::Ref(0); 32] }
+                       registers: vec![HeapCellRef::Ref(0); 32] }
+    }
+
+    fn register_mut(&mut self, r: RegType) -> &mut HeapCellRef {
+        match r {
+            RegType::Temp(r) => &mut self.registers[r],
+            RegType::Perm(r) => &mut self.stack[r]
+        }
+    }
+
+    fn lookup(&self, a: Addr) -> HeapCellRef {
+        match a {
+            Addr::HeapCell(r)  => self.heap[r].as_ref(r),
+            Addr::RegNum(r)    => self.registers[r],
+            Addr::StackCell(s) => self.stack[s]
+        }
     }
 
     fn deref(&self, a: Addr) -> Addr {
         let mut a = a;
 
         loop {
-            if let &HeapCellValue::Ref(value) = &self[a] {
+            if let HeapCellRef::Ref(value) = self.lookup(a) {
                 if let Addr::HeapCell(av) = a {
                     if value != av {
                         a = Addr::HeapCell(value);
@@ -180,10 +247,10 @@ impl MachineState {
         loop {
             match a {
                 addr @ Addr::RegNum(_) | addr @ Addr::StackCell(_) => {
-                    if let HeapCellValue::Ref(hc) = self[addr] {
+                    if let HeapCellRef::Ref(hc) = self.lookup(addr) {
                         a = Addr::HeapCell(hc);
                     } else if Self::is_unbound(&self.heap[val], val) {
-                        self.heap[val] = self[addr].clone();
+                        self.heap[val] = HeapCellValue::from(self.lookup(addr));
                         break;
                     } else {
                         self.fail = true;
@@ -216,19 +283,19 @@ impl MachineState {
             let d2 = self.deref(pdl.pop().unwrap());
 
             if d1 != d2 {
-                match (&self[d1], &self[d2]) {
-                    (&HeapCellValue::Ref(hc), _) =>
+                match (self.lookup(d1), self.lookup(d2)) {
+                    (HeapCellRef::Ref(hc), _) =>
                         self.bind(d2, hc),
-                    (_, &HeapCellValue::Ref(hc)) =>
+                    (_, HeapCellRef::Ref(hc)) =>
                         self.bind(d1, hc),
-                    (&HeapCellValue::Str(a1), &HeapCellValue::Str(a2)) => {
+                    (HeapCellRef::Str(a1), HeapCellRef::Str(a2)) => {
                         let r1 = &self.heap[a1];
                         let r2 = &self.heap[a2];
 
                         if let &HeapCellValue::NamedStr(n1, ref f1) = r1 {
                             if let &HeapCellValue::NamedStr(n2, ref f2) = r2 {
                                 if n1 == n2 && *f1 == *f2 {
-                                    for i in 1 .. n1 {
+                                    for i in 1 .. n1 + 1 {
                                         pdl.push(Addr::HeapCell(a1 + i));
                                         pdl.push(Addr::HeapCell(a2 + i));
                                     }
@@ -240,7 +307,6 @@ impl MachineState {
 
                         self.fail = true;
                     },
-                    _ => self.fail = true,
                 };
             }
         }
@@ -252,29 +318,33 @@ impl MachineState {
                 self.heap.push(HeapCellValue::Str(self.h + 1));
                 self.heap.push(HeapCellValue::NamedStr(arity, name.clone()));
 
-                self[Addr::from(reg)] = self.heap[self.h].clone();
+                *self.register_mut(reg) = HeapCellRef::Str(self.h + 1);
 
                 self.h += 2;
             },
             &QueryInstruction::PutValue(norm, arg) =>
-                self.registers[arg] = self[Addr::from(norm)].clone(),
+                self.registers[arg] = match norm {
+                    RegType::Temp(reg) => self.registers[reg],
+                    RegType::Perm(reg) => self.stack[reg]
+                },
             &QueryInstruction::PutVariable(norm, arg) => {
                 self.heap.push(HeapCellValue::Ref(self.h));
 
-                self[Addr::from(norm)] = self.heap[self.h].clone();
-                self.registers[arg] = self.heap[self.h].clone();
+                *self.register_mut(norm) = HeapCellRef::Ref(self.h);
+                self.registers[arg] = HeapCellRef::Ref(self.h);
 
                 self.h += 1;
             },
             &QueryInstruction::SetVariable(reg) => {
                 self.heap.push(HeapCellValue::Ref(self.h));
-                self[Addr::from(reg)] = self.heap[self.h].clone();
+                *self.register_mut(reg) = HeapCellRef::Ref(self.h);
 
                 self.h += 1;
             },
             &QueryInstruction::SetValue(reg) => {
-                let heap_val = self[Addr::from(reg)].clone();
-                self.heap.push(heap_val);
+                let heap_val = self.lookup(Addr::from(reg));
+                self.heap.push(HeapCellValue::from(heap_val));
+
                 self.h += 1;
             },
         }
@@ -285,8 +355,8 @@ impl MachineState {
             &FactInstruction::GetStructure(_, ref name, arity, reg) => {
                 let addr = self.deref(Addr::from(reg));
 
-                match &self[addr] {
-                    &HeapCellValue::Str(a) => {
+                match self.lookup(addr) {
+                    HeapCellRef::Str(a) => {
                         let result = &self.heap[a];
 
                         if let &HeapCellValue::NamedStr(narity, ref str) = result {
@@ -298,32 +368,30 @@ impl MachineState {
                             }
                         }
                     },
-                    &HeapCellValue::Ref(r) => {
+                    HeapCellRef::Ref(_) => {
                         self.heap.push(HeapCellValue::Str(self.h + 1));
                         self.heap.push(HeapCellValue::NamedStr(arity, name.clone()));
 
                         let h = self.h;
 
-                        self.bind(Addr::HeapCell(r), h);
+                        self.bind(addr, h);
 
                         self.h += 2;
                         self.mode = MachineMode::Write;
-                    },
-                    _ => self.fail = true,
+                    }
                 };
             },
             &FactInstruction::GetVariable(norm, arg) =>
-                self[Addr::from(norm)] = self.registers[arg].clone(),
+                *self.register_mut(norm) = self.registers[arg],
             &FactInstruction::GetValue(norm, arg) =>
                 self.unify(Addr::from(norm), Addr::RegNum(arg)),
             &FactInstruction::UnifyVariable(reg) => {
                 match self.mode {
                     MachineMode::Read  =>
-                        self[Addr::from(reg)] = self.heap[self.s].clone(),
+                        *self.register_mut(reg) = self.heap[self.s].as_ref(self.s),
                     MachineMode::Write => {
                         self.heap.push(HeapCellValue::Ref(self.h));
-
-                        self[Addr::from(reg)] = self.heap[self.h].clone();
+                        *self.register_mut(reg) = HeapCellRef::Ref(self.h);
                         self.h += 1;
                     }
                 };
@@ -337,8 +405,8 @@ impl MachineState {
                     MachineMode::Read  =>
                         self.unify(Addr::from(reg), Addr::HeapCell(s)),
                     MachineMode::Write => {
-                        let heap_val = self[Addr::from(reg)].clone();
-                        self.heap.push(heap_val);
+                        let heap_val = self.lookup(Addr::from(reg));
+                        self.heap.push(HeapCellValue::from(heap_val));
                         self.h += 1;
                     }
                 };
@@ -371,12 +439,11 @@ impl MachineState {
                 self.p = self.stack.get_cp();
                 self.stack.pop();
             },
-            &ControlInstruction::Proceed => {
-                self.p = self.cp;
-            }
+            &ControlInstruction::Proceed =>
+                self.p = self.cp,
         };
     }
-    
+
     fn reset(&mut self) {
         self.h = 0;
         self.s = 0;
@@ -387,6 +454,6 @@ impl MachineState {
         self.heap.clear();
         self.mode = MachineMode::Write;
         self.stack = Stack::new();
-        self.registers = vec![HeapCellValue::Ref(0); 32];
+        self.registers = vec![HeapCellRef::Ref(0); 32];
     }
 }
index 503e5366252c7addc0833e8c7693aef5ee33f97e..fcf899c0d5604ac378257dbc336e22ba3bdfcd74 100644 (file)
@@ -1,4 +1,5 @@
 pub mod ast;
+pub mod heapview;
 pub mod iterators;
 pub mod l2_parser;
 pub mod codegen;
index 35c777708ca8256cfb5e2203f717fcab059b6eb4..91fe8656d3c57da89289d02f6c6dbae37cc662c0 100644 (file)
@@ -5,22 +5,22 @@ use std::vec::Vec;
 
 struct Frame {
     cp: CodePtr,
-    perms: Vec<HeapCellValue>
+    perms: Vec<HeapCellRef>
 }
 
 impl Frame {
     fn new(cp: CodePtr, n: usize) -> Self {
         Frame {
             cp: cp,
-            perms: vec![HeapCellValue::Ref(0); n]
+            perms: vec![HeapCellRef::Ref(0); n]
         }
     }
 
-    fn read_pv(&self, i: usize) -> &HeapCellValue {
+    fn read_pv(&self, i: usize) -> &HeapCellRef {
         self.perms.index(i)
     }
 
-    fn read_pv_mut(&mut self, i: usize) -> &mut HeapCellValue {
+    fn read_pv_mut(&mut self, i: usize) -> &mut HeapCellRef {
         self.perms.index_mut(i)
     }
 }
@@ -46,7 +46,7 @@ impl Stack {
 }
 
 impl Index<usize> for Stack {
-    type Output = HeapCellValue;
+    type Output = HeapCellRef;
 
     fn index(&self, index: usize) -> &Self::Output {
         self.0.last().unwrap().read_pv(index - 1)
index f285cbf75da2cdeee0f84dfc464f35d3cfc1f5f0..1d8ed6598317874462f3bc654ab4f86883ee0932 100644 (file)
@@ -23,6 +23,7 @@ fn l2_repl() {
             break;
         } else if &*buffer == "clear\n" {
             wam = Machine::new();
+            continue;
         }
 
         let mut cg = CodeGenerator::new();
@@ -38,13 +39,18 @@ fn l2_repl() {
             },
             &Ok(TopLevel::Query(ref query)) => {
                 let compiled_query = cg.compile_query(&query);
-                let succeeded = wam.execute_query(compiled_query);
-
-                if succeeded {
-                    println!("yes");
-                } else {
-                    println!("no");
-                }                
+                let output = wam.run_query(compiled_query, &cg);
+
+                match output {
+                    Some(result) => {
+                        println!("yes");
+
+                        if result != "" {
+                            println!("{}", result);
+                        }
+                    },
+                    None => println!("no")
+                }
             },
             &Err(_) => println!("Grammatical error of some kind!"),
         };