From: bakaq Date: Wed, 14 Aug 2024 21:44:10 +0000 (-0300) Subject: Implement run_query() in terms of run_query_iter() X-Git-Tag: v0.10.0~120^2~1 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=bc262db6d730dadbeb5ce6995a86640b5f342e97;p=scryer-prolog.git Implement run_query() in terms of run_query_iter() --- diff --git a/src/machine/lib_machine.rs b/src/machine/lib_machine.rs index f068c908..a420d79e 100644 --- a/src/machine/lib_machine.rs +++ b/src/machine/lib_machine.rs @@ -13,7 +13,7 @@ use indexmap::IndexMap; use super::{ streams::Stream, Atom, AtomCell, HeapCellValue, HeapCellValueTag, Machine, MachineConfig, - QueryResolution, QueryResolutionLine, QueryResult, Value, + QueryResolutionLine, QueryResult, Value, }; pub struct QueryState<'a> { @@ -180,171 +180,7 @@ impl Machine { } pub fn run_query(&mut self, query: String) -> QueryResult { - // println!("Query: {}", query); - // Parse the query so we can analyze and then call the term - let mut parser = Parser::new( - Stream::from_owned_string(query, &mut self.machine_st.arena), - &mut self.machine_st, - ); - let op_dir = CompositeOpDir::new(&self.indices.op_dir, None); - let term = parser - .read_term(&op_dir, Tokens::Default) - .expect("Failed to parse query"); - - self.allocate_stub_choice_point(); - - // Write parsed term to heap - let term_write_result = - write_term_to_heap(&term, &mut self.machine_st.heap, &self.machine_st.atom_tbl) - .expect("couldn't write term to heap"); - - 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(); - - // Write term to heap - self.machine_st.registers[1] = self.machine_st.heap[term_write_result.heap_loc]; - - self.machine_st.cp = LIB_QUERY_SUCCESS; // BREAK_FROM_DISPATCH_LOOP_LOC; - let call_index_p = self - .indices - .code_dir - .get(&(atom!("call"), 1)) - .expect("couldn't get code index") - .local() - .unwrap(); - - self.machine_st.execute_at_index(1, call_index_p); - - let stub_b = self.machine_st.b; - - let mut matches: Vec = Vec::new(); - // Call the term - loop { - self.dispatch_loop(); - - //println!("b: {}", self.machine_st.b); - //println!("stub_b: {}", stub_b); - //println!("fail: {}", self.machine_st.fail); - - if !self.machine_st.ball.stub.is_empty() { - // NOTE: this means an exception was thrown, at which - // point we backtracked to the stub choice point. - // this should halt the search for solutions as it - // does in the Scryer top-level. the exception term is - // contained in self.machine_st.ball. - let error_string = self - .machine_st - .ball - .stub - .iter() - .filter(|h| { - matches!( - h.get_tag(), - HeapCellValueTag::Atom | HeapCellValueTag::Fixnum - ) - }) - .map(|h| match h.get_tag() { - HeapCellValueTag::Atom => { - let (name, _) = cell_as_atom_cell!(h).get_name_and_arity(); - name.as_str().to_string() - } - HeapCellValueTag::Fixnum => h.get_value().clone().to_string(), - _ => unreachable!(), - }) - .collect::>() - .join(" "); - - return Err(error_string); - } - - /* - if self.machine_st.fail { - // NOTE: only print results on success - self.machine_st.fail = false; - println!("fail!"); - matches.push(QueryResolutionLine::False); - break; - }; - */ - - if self.machine_st.p == LIB_QUERY_SUCCESS { - if term_write_result.var_dict.is_empty() { - matches.push(QueryResolutionLine::True); - break; - } - } else if self.machine_st.p == BREAK_FROM_DISPATCH_LOOP_LOC { - // NOTE: only print results on success - // self.machine_st.fail = false; - // println!("b == stub_b"); - matches.push(QueryResolutionLine::False); - break; - } - - let mut bindings: BTreeMap = BTreeMap::new(); - - for (var_key, term_to_be_printed) in &term_write_result.var_dict { - if var_key.to_string().starts_with('_') { - continue; - } - let mut printer = HCPrinter::new( - &mut self.machine_st.heap, - Arc::clone(&self.machine_st.atom_tbl), - &mut self.machine_st.stack, - &self.indices.op_dir, - PrinterOutputter::new(), - *term_to_be_printed, - ); - - printer.ignore_ops = false; - printer.numbervars = true; - printer.quoted = true; - printer.max_depth = 1000; // NOTE: set this to 0 for unbounded depth - printer.double_quotes = true; - printer.var_names.clone_from(&var_names); - - let outputter = printer.print(); - - let output: String = outputter.result(); - // println!("Result: {} = {}", var_key.to_string(), output); - - if var_key.to_string() != output { - bindings.insert( - var_key.to_string(), - Value::try_from(output).expect("Couldn't convert Houtput to Value"), - ); - } - } - - matches.push(QueryResolutionLine::Match(bindings)); - - // NOTE: there are outstanding choicepoints, backtrack - // through them for further solutions. if - // self.machine_st.b == stub_b we've backtracked to the stub - // choice point, so we should break. - self.machine_st.backtrack(); - - if self.machine_st.b <= stub_b { - // NOTE: out of choicepoints to backtrack through, no - // more solutions to gather. - break; - } - } - - // NOTE: deallocate stub choice point - if self.machine_st.b == stub_b { - self.trust_me(); - } - - Ok(QueryResolution::from(matches)) + self.run_query_iter(query).collect() } pub fn run_query_iter(&mut self, query: String) -> QueryState { diff --git a/src/machine/parsed_results.rs b/src/machine/parsed_results.rs index 8ca6f8e8..0dd8236f 100644 --- a/src/machine/parsed_results.rs +++ b/src/machine/parsed_results.rs @@ -5,6 +5,7 @@ use std::collections::BTreeMap; use std::collections::HashMap; use std::fmt::Display; use std::fmt::Write; +use std::iter::FromIterator; pub type QueryResult = Result; @@ -198,6 +199,14 @@ impl From> for QueryResolution { } } +impl FromIterator for QueryResolution { + fn from_iter>(iter: I) -> Self { + // TODO: Probably a good idea to implement From> based on this + // instead. + iter.into_iter().collect::>().into() + } +} + fn split_response_string(input: &str) -> Vec { let mut level_bracket = 0; let mut level_parenthesis = 0;