fix bug in printer over lists.
This commit is contained in:
@@ -5,26 +5,15 @@ use std::vec::Vec;
|
|||||||
|
|
||||||
pub struct HeapCellPreOrderIterator<'a> {
|
pub struct HeapCellPreOrderIterator<'a> {
|
||||||
machine_st : &'a MachineState,
|
machine_st : &'a MachineState,
|
||||||
state_stack : Vec<Ref>
|
state_stack : Vec<Addr>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> HeapCellPreOrderIterator<'a> {
|
impl<'a> HeapCellPreOrderIterator<'a> {
|
||||||
pub fn new(machine_st: &'a MachineState, r: Ref) -> Self
|
pub fn new(machine_st: &'a MachineState, a: Addr) -> Self
|
||||||
{
|
{
|
||||||
HeapCellPreOrderIterator {
|
HeapCellPreOrderIterator {
|
||||||
machine_st,
|
machine_st,
|
||||||
state_stack: vec![r]
|
state_stack: vec![a]
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// called under the assumption that the location at r is about to
|
|
||||||
// be visited, and so any follow up states need to be added to
|
|
||||||
// state_stack. returns the dereferenced Addr from Ref.
|
|
||||||
fn follow(&mut self, r: Ref) -> Addr
|
|
||||||
{
|
|
||||||
match r {
|
|
||||||
Ref::HeapCell(hc) => self.follow_heap(hc),
|
|
||||||
Ref::StackCell(fr, sc) => self.follow_addr(Addr::StackCell(fr, sc))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,34 +22,35 @@ impl<'a> HeapCellPreOrderIterator<'a> {
|
|||||||
match &self.machine_st.heap[h] {
|
match &self.machine_st.heap[h] {
|
||||||
&HeapCellValue::NamedStr(arity, _, _) => {
|
&HeapCellValue::NamedStr(arity, _, _) => {
|
||||||
for idx in (1 .. arity + 1).rev() {
|
for idx in (1 .. arity + 1).rev() {
|
||||||
self.state_stack.push(Ref::HeapCell(h + idx));
|
self.state_stack.push(Addr::HeapCell(h + idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr::HeapCell(h)
|
Addr::HeapCell(h)
|
||||||
},
|
},
|
||||||
&HeapCellValue::Addr(ref a) =>
|
&HeapCellValue::Addr(ref a) =>
|
||||||
self.follow_addr(a.clone())
|
self.follow(a.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn follow_addr(&mut self, addr: Addr) -> Addr
|
// called under the assumption that the location at r is about to
|
||||||
|
// be visited, and so any follow up states need to be added to
|
||||||
|
// state_stack. returns the dereferenced Addr from Ref.
|
||||||
|
fn follow(&mut self, addr: Addr) -> Addr
|
||||||
{
|
{
|
||||||
let da = self.machine_st.store(self.machine_st.deref(addr));
|
let da = self.machine_st.store(self.machine_st.deref(addr));
|
||||||
|
|
||||||
match &da {
|
match &da {
|
||||||
&Addr::Con(_) => da,
|
&Addr::Con(_) => da,
|
||||||
&Addr::Lis(a) => {
|
&Addr::Lis(a) => {
|
||||||
self.state_stack.push(Ref::HeapCell(a + 1));
|
self.state_stack.push(Addr::HeapCell(a + 1));
|
||||||
self.state_stack.push(Ref::HeapCell(a));
|
self.state_stack.push(Addr::HeapCell(a));
|
||||||
|
|
||||||
da
|
da
|
||||||
},
|
},
|
||||||
&Addr::HeapCell(_) | &Addr::StackCell(_, _) =>
|
&Addr::HeapCell(_) | &Addr::StackCell(_, _) =>
|
||||||
da,
|
da,
|
||||||
&Addr::Str(s) => {
|
&Addr::Str(s) =>
|
||||||
self.follow_heap(s); // record terms of structure.
|
self.follow_heap(s) // record terms of structure.
|
||||||
Addr::HeapCell(s)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,8 +59,8 @@ impl<'a> Iterator for HeapCellPreOrderIterator<'a> {
|
|||||||
type Item = HeapCellValue;
|
type Item = HeapCellValue;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if let Some(r) = self.state_stack.pop() {
|
if let Some(a) = self.state_stack.pop() {
|
||||||
match self.follow(r) {
|
match self.follow(a) {
|
||||||
Addr::HeapCell(h) => Some(self.machine_st.heap[h].clone()),
|
Addr::HeapCell(h) => Some(self.machine_st.heap[h].clone()),
|
||||||
Addr::StackCell(fr, sc) => {
|
Addr::StackCell(fr, sc) => {
|
||||||
let heap_val = HeapCellValue::Addr(self.machine_st.and_stack[fr][sc].clone());
|
let heap_val = HeapCellValue::Addr(self.machine_st.and_stack[fr][sc].clone());
|
||||||
@@ -129,7 +119,7 @@ impl<'a> Iterator for HeapCellPostOrderIterator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
pub fn post_order_iter<'a>(&'a self, r: Ref) -> HeapCellPostOrderIterator<'a> {
|
pub fn post_order_iter<'a>(&'a self, a: Addr) -> HeapCellPostOrderIterator<'a> {
|
||||||
HeapCellPostOrderIterator::new(HeapCellPreOrderIterator::new(self, r))
|
HeapCellPostOrderIterator::new(HeapCellPreOrderIterator::new(self, a))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,31 +259,15 @@ impl MachineState {
|
|||||||
self.trail(r1);
|
self.trail(r1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_var<Fmt, Outputter>(&self, r: Ref, fmt: Fmt, output: Outputter) -> Outputter
|
pub(super) fn print_term<Fmt, Outputter>(&self, a: Addr, fmt: Fmt, output: Outputter) -> Outputter
|
||||||
where Fmt: HeapCellValueFormatter, Outputter: HeapCellValueOutputter
|
where Fmt: HeapCellValueFormatter, Outputter: HeapCellValueOutputter
|
||||||
{
|
{
|
||||||
let iter = HeapCellPreOrderIterator::new(&self, r);
|
let iter = HeapCellPreOrderIterator::new(&self, a);
|
||||||
let printer = HeapCellPrinter::new(iter, fmt, output);
|
let printer = HeapCellPrinter::new(iter, fmt, output);
|
||||||
|
|
||||||
printer.print()
|
printer.print()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn print_term<Fmt, Outputter>(&self, addr: &Addr, fmt: Fmt, mut output: Outputter)
|
|
||||||
-> Outputter
|
|
||||||
where Fmt: HeapCellValueFormatter, Outputter: HeapCellValueOutputter
|
|
||||||
{
|
|
||||||
match addr {
|
|
||||||
&Addr::Con(ref c) => {
|
|
||||||
output.append(format!("{}", c).as_str());
|
|
||||||
output
|
|
||||||
},
|
|
||||||
&Addr::Lis(h) | &Addr::HeapCell(h) | &Addr::Str(h) =>
|
|
||||||
self.print_var(Ref::HeapCell(h), fmt, output),
|
|
||||||
&Addr::StackCell(fr, sc) =>
|
|
||||||
self.print_var(Ref::StackCell(fr, sc), fmt, output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unify(&mut self, a1: Addr, a2: Addr) {
|
fn unify(&mut self, a1: Addr, a2: Addr) {
|
||||||
let mut pdl = vec![a1, a2];
|
let mut pdl = vec![a1, a2];
|
||||||
|
|
||||||
@@ -508,15 +492,9 @@ impl MachineState {
|
|||||||
return Ok(n.clone());
|
return Ok(n.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = match a {
|
|
||||||
Addr::Str(h) | Addr::HeapCell(h) => Ok(Ref::HeapCell(h)),
|
|
||||||
Addr::StackCell(fr, sc) => Ok(Ref::StackCell(fr, sc)),
|
|
||||||
_ => Err(instantiation_err.clone())
|
|
||||||
}?;
|
|
||||||
|
|
||||||
let mut interms: Vec<Number> = Vec::with_capacity(64);
|
let mut interms: Vec<Number> = Vec::with_capacity(64);
|
||||||
|
|
||||||
for heap_val in self.post_order_iter(r) {
|
for heap_val in self.post_order_iter(a) {
|
||||||
match heap_val {
|
match heap_val {
|
||||||
HeapCellValue::NamedStr(2, name, Some(Fixity::In)) => {
|
HeapCellValue::NamedStr(2, name, Some(Fixity::In)) => {
|
||||||
let a2 = interms.pop().unwrap();
|
let a2 = interms.pop().unwrap();
|
||||||
@@ -1641,7 +1619,7 @@ impl MachineState {
|
|||||||
self.p += 1;
|
self.p += 1;
|
||||||
},
|
},
|
||||||
&ControlInstruction::DisplayCall => {
|
&ControlInstruction::DisplayCall => {
|
||||||
let output = self.print_term(&self[temp_v!(1)],
|
let output = self.print_term(self[temp_v!(1)].clone(),
|
||||||
DisplayFormatter {},
|
DisplayFormatter {},
|
||||||
PrinterOutputter::new());
|
PrinterOutputter::new());
|
||||||
|
|
||||||
@@ -1650,7 +1628,7 @@ impl MachineState {
|
|||||||
self.p += 1;
|
self.p += 1;
|
||||||
},
|
},
|
||||||
&ControlInstruction::DisplayExecute => {
|
&ControlInstruction::DisplayExecute => {
|
||||||
let output = self.print_term(&self[temp_v!(1)],
|
let output = self.print_term(self[temp_v!(1)].clone(),
|
||||||
DisplayFormatter {},
|
DisplayFormatter {},
|
||||||
PrinterOutputter::new());
|
PrinterOutputter::new());
|
||||||
|
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ impl Machine {
|
|||||||
let h = self.ms.heap.h;
|
let h = self.ms.heap.h;
|
||||||
self.ms.copy_and_align_ball_to_heap();
|
self.ms.copy_and_align_ball_to_heap();
|
||||||
|
|
||||||
let msg = self.ms.print_term(&Addr::HeapCell(h),
|
let msg = self.ms.print_term(Addr::HeapCell(h),
|
||||||
TermFormatter {},
|
TermFormatter {},
|
||||||
PrinterOutputter::new())
|
PrinterOutputter::new())
|
||||||
.result();
|
.result();
|
||||||
@@ -322,7 +322,7 @@ impl Machine {
|
|||||||
output.append(var.as_str());
|
output.append(var.as_str());
|
||||||
output.append(" = ");
|
output.append(" = ");
|
||||||
|
|
||||||
output = self.ms.print_term(addr, TermFormatter {}, output);
|
output = self.ms.print_term(addr.clone(), TermFormatter {}, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
output
|
output
|
||||||
|
|||||||
60
src/tests.rs
60
src/tests.rs
@@ -588,7 +588,7 @@ fn test_queries_on_conjuctive_queries() {
|
|||||||
submit(&mut wam, "p(a, [f(g(X))]).");
|
submit(&mut wam, "p(a, [f(g(X))]).");
|
||||||
submit(&mut wam, "q(Y, c).");
|
submit(&mut wam, "q(Y, c).");
|
||||||
|
|
||||||
assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).", [["Y = f(g(_9))", "X = a", "Z = c"]]);
|
assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).", [["Y = [f(g(_9))]", "X = a", "Z = c"]]);
|
||||||
assert_prolog_failure!(&mut wam, "?- p(X, Y), q(Y, X).");
|
assert_prolog_failure!(&mut wam, "?- p(X, Y), q(Y, X).");
|
||||||
|
|
||||||
submit(&mut wam, "member(X, [X|_]).
|
submit(&mut wam, "member(X, [X|_]).
|
||||||
@@ -620,51 +620,51 @@ fn test_queries_on_conjuctive_queries() {
|
|||||||
submit(&mut wam, "q(Y, c).");
|
submit(&mut wam, "q(Y, c).");
|
||||||
|
|
||||||
assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).",
|
assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).",
|
||||||
[["X = a", "Z = c", "Y = f(g(_9))"],
|
[["X = a", "Z = c", "Y = [f(g(_9))]"],
|
||||||
["X = _0", "Z = c", "Y = c"]]);
|
["X = _0", "Z = c", "Y = c"]]);
|
||||||
assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, Z).",
|
assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, Z).",
|
||||||
[["Z = c", "Y = f(g(_9))", "X = a"]]);
|
[["Z = c", "Y = [f(g(_9))]", "X = a"]]);
|
||||||
|
|
||||||
submit(&mut wam, "q([f(g(x))], Z). q([f(g(y))], Y). q([f(g(z))], a).");
|
submit(&mut wam, "q([f(g(x))], Z). q([f(g(y))], Y). q([f(g(z))], a).");
|
||||||
|
|
||||||
assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).",
|
assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, Z).",
|
||||||
[["Z = _10", "X = a", "Y = f(g(x))"],
|
[["Z = _10", "X = a", "Y = [f(g(x))]"],
|
||||||
["Z = _10", "X = a", "Y = f(g(y))"],
|
["Z = _10", "X = a", "Y = [f(g(y))]"],
|
||||||
["Z = a", "X = a", "Y = f(g(z))"]]);
|
["Z = a", "X = a", "Y = [f(g(z))]"]]);
|
||||||
assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, Z).",
|
assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, Z).",
|
||||||
[["X = a", "Y = f(g(x))", "Z = _10"],
|
[["X = a", "Y = [f(g(x))]", "Z = _10"],
|
||||||
["X = a", "Y = f(g(y))", "Z = _10"],
|
["X = a", "Y = [f(g(y))]", "Z = _10"],
|
||||||
["X = a", "Y = f(g(z))", "Z = a"]]);
|
["X = a", "Y = [f(g(z))]", "Z = a"]]);
|
||||||
assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, X).",
|
assert_prolog_success!(&mut wam, "?- p(X, Y), !, q(Y, X).",
|
||||||
[["X = a", "Y = f(g(x))"],
|
[["X = a", "Y = [f(g(x))]"],
|
||||||
["X = a", "Y = f(g(y))"],
|
["X = a", "Y = [f(g(y))]"],
|
||||||
["X = a", "Y = f(g(z))"]]);
|
["X = a", "Y = [f(g(z))]"]]);
|
||||||
|
|
||||||
submit(&mut wam, "p(X, [f(g(x))]). p(X, [f(g(y))]). p(X, [f(g(z))]).");
|
submit(&mut wam, "p(X, [f(g(x))]). p(X, [f(g(y))]). p(X, [f(g(z))]).");
|
||||||
|
|
||||||
assert_prolog_failure!(&mut wam, "?- q(f(X), Y), p(X, Y).");
|
assert_prolog_failure!(&mut wam, "?- q(f(X), Y), p(X, Y).");
|
||||||
assert_prolog_success!(&mut wam, "?- q(X, Y), p(X, Y).",
|
assert_prolog_success!(&mut wam, "?- q(X, Y), p(X, Y).",
|
||||||
[["Y = [f(g(x))]", "X = f(g(x))"],
|
[["Y = [f(g(x))]", "X = [f(g(x))]"],
|
||||||
["Y = [f(g(y))]", "X = f(g(x))"],
|
["Y = [f(g(y))]", "X = [f(g(x))]"],
|
||||||
["Y = [f(g(z))]", "X = f(g(x))"],
|
["Y = [f(g(z))]", "X = [f(g(x))]"],
|
||||||
["Y = [f(g(x))]", "X = f(g(y))"],
|
["Y = [f(g(x))]", "X = [f(g(y))]"],
|
||||||
["Y = [f(g(y))]", "X = f(g(y))"],
|
["Y = [f(g(y))]", "X = [f(g(y))]"],
|
||||||
["Y = [f(g(z))]", "X = f(g(y))"]]);
|
["Y = [f(g(z))]", "X = [f(g(y))]"]]);
|
||||||
assert_prolog_success!(&mut wam, "?- p(X, Y), q(X, Y).",
|
assert_prolog_success!(&mut wam, "?- p(X, Y), q(X, Y).",
|
||||||
[["Y = f(g(x))", "X = [f(g(x))]"],
|
[["Y = [f(g(x))]", "X = [f(g(x))]"],
|
||||||
["Y = f(g(x))", "X = [f(g(y))]"],
|
["Y = [f(g(x))]", "X = [f(g(y))]"],
|
||||||
["Y = f(g(y))", "X = [f(g(x))]"],
|
["Y = [f(g(y))]", "X = [f(g(x))]"],
|
||||||
["Y = f(g(y))", "X = [f(g(y))]"],
|
["Y = [f(g(y))]", "X = [f(g(y))]"],
|
||||||
["Y = f(g(z))", "X = [f(g(x))]"],
|
["Y = [f(g(z))]", "X = [f(g(x))]"],
|
||||||
["Y = f(g(z))", "X = [f(g(y))]"]]);
|
["Y = [f(g(z))]", "X = [f(g(y))]"]]);
|
||||||
assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, X).",
|
assert_prolog_success!(&mut wam, "?- p(X, Y), q(Y, X).",
|
||||||
[["Y = f(g(x))", "X = s_0_2"],
|
[["Y = [f(g(x))]", "X = s_0_2"],
|
||||||
["Y = f(g(y))", "X = s_0_2"],
|
["Y = [f(g(y))]", "X = s_0_2"],
|
||||||
["Y = f(g(z))", "X = a"]]);
|
["Y = [f(g(z))]", "X = a"]]);
|
||||||
assert_prolog_success!(&mut wam, "?- q(X, Y), p(Y, X).",
|
assert_prolog_success!(&mut wam, "?- q(X, Y), p(Y, X).",
|
||||||
[["Y = s_0_1", "X = f(g(x))"],
|
[["Y = s_0_1", "X = [f(g(x))]"],
|
||||||
["Y = s_0_1", "X = f(g(y))"],
|
["Y = s_0_1", "X = [f(g(y))]"],
|
||||||
["Y = a" , "X = f(g(z))"]]);
|
["Y = a" , "X = [f(g(z))]"]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user