mthom's changes to run_query with backtracking

This commit is contained in:
Nicolas Luck
2023-09-15 10:04:11 +02:00
parent 6bdd7f3a3f
commit 48283c4dbc

View File

@@ -7,6 +7,9 @@ use crate::machine::BREAK_FROM_DISPATCH_LOOP_LOC;
use crate::machine::mock_wam::{CompositeOpDir, Term, Fixnum}; use crate::machine::mock_wam::{CompositeOpDir, Term, Fixnum};
use crate::parser::parser::{Parser, Tokens}; use crate::parser::parser::{Parser, Tokens};
use crate::read::write_term_to_heap; use crate::read::write_term_to_heap;
use crate::machine::machine_indices::VarKey;
use crate::parser::ast::{Var, VarPtr};
use indexmap::IndexMap;
use super::{ use super::{
Machine, MachineConfig, QueryResult, QueryResolutionLine, Machine, MachineConfig, QueryResult, QueryResolutionLine,
@@ -80,37 +83,68 @@ impl Machine {
// Write term to heap // Write term to heap
self.machine_st.registers[1] = self.machine_st.heap[term_write_result.heap_loc]; self.machine_st.registers[1] = self.machine_st.heap[term_write_result.heap_loc];
// Call the term
self.machine_st.cp = BREAK_FROM_DISPATCH_LOOP_LOC; self.machine_st.cp = BREAK_FROM_DISPATCH_LOOP_LOC;
self.machine_st.p = self.indices.code_dir.get(&(atom!("call"), 1)).expect("couldn't get code index").local().unwrap(); self.machine_st.p = self.indices.code_dir.get(&(atom!("call"), 1)).expect("couldn't get code index").local().unwrap();
self.dispatch_loop();
let var_names: IndexMap<_, _> = term_write_result.var_dict.iter()
.map(|(var_key, cell)| match var_key {
// NOTE: not the intention behind Var::InSitu here but
// we can hijack it to store anonymous variables
// without creating problems.
VarKey::AnonVar(h) => (*cell, VarPtr::from(Var::InSitu(*h))),
VarKey::VarPtr(var_ptr) => (*cell, var_ptr.clone()),
})
.collect();
// NOTE: mimic writeq settings here (see arguments of '$write_term'/8 at builtins.pl:693) // Call the term
self.machine_st.registers[8] = atom_as_cell!(atom!("false")); loop {
self.machine_st.registers[7] = fixnum_as_cell!(Fixnum::build_with(10)); self.dispatch_loop();
self.machine_st.registers[6] = empty_list_as_cell!();
self.machine_st.registers[5] = atom_as_cell!(atom!("true"));
self.machine_st.registers[4] = atom_as_cell!(atom!("true"));
self.machine_st.registers[3] = atom_as_cell!(atom!("false"));
let term_to_be_printed = self.machine_st.store(self.machine_st.deref(self.machine_st.registers[2])); if self.machine_st.fail {
// NOTE: only print results on success
self.machine_st.fail = false;
break;
}
let mut printer = HCPrinter::new( for (var_key, term_to_be_printed) in &term_write_result.var_dict {
&mut self.machine_st.heap, let mut printer = HCPrinter::new(
Arc::clone(&self.machine_st.atom_tbl), &mut self.machine_st.heap,
&mut self.machine_st.stack, Arc::clone(&self.machine_st.atom_tbl),
&self.indices.op_dir, &mut self.machine_st.stack,
PrinterOutputter::new(), &self.indices.op_dir,
term_to_be_printed, PrinterOutputter::new(),
); *term_to_be_printed,
);
println!("Varnames: {:?}", printer.var_names); // NOTE: I've converted the former register settings
printer.max_depth = 1000; // for '$write_term'/8 to printer settings. Registers
let output = printer.print(); // are not read by the printer.
println!("Print: {:?}", output); printer.ignore_ops = false;
println!("Result: {:?}", output.result()); printer.numbervars = true;
printer.quoted = true;
printer.max_depth = 1000; // NOTE: set this to 0 for unbounded depth
printer.double_quotes = false;
printer.var_names = var_names.clone();
println!("Varnames: {:?}", printer.var_names);
let output = printer.print();
println!("Print: {:?}", output);
println!("Result: {} = {}", var_key.to_string(), output.result());
}
if self.machine_st.b > 0 {
// NOTE: there are outstanding choicepoints, backtrack
// through them for further solutions.
self.machine_st.backtrack();
} else {
// NOTE: out of choicepoints to backtrack through, no
// more solutions to gather.
break;
}
}
Err("not implementend".to_string()) Err("not implementend".to_string())
} }