From 2f99bb025c304b5a99301891d018c078d36c1229 Mon Sep 17 00:00:00 2001 From: Nicolas Luck Date: Thu, 27 Jul 2023 11:41:52 +0200 Subject: [PATCH] Add consult that works with streams / strings in library use-case --- src/loader.pl | 5 ++- src/machine/lib_machine.rs | 81 +++++++++++++++++++++++++++++++++++++- src/machine/mod.rs | 5 --- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/loader.pl b/src/loader.pl index fe3d6fe2..8365d761 100644 --- a/src/loader.pl +++ b/src/loader.pl @@ -562,7 +562,10 @@ use_module(Module, Exports, Evacuable) :- ) ). - +consult_stream(Stream, PathFileName) :- + '$push_load_state_payload'(Evacuable), + file_load(Stream, PathFileName, Subevacuable), + '$use_module'(Evacuable, Subevacuable, _). check_predicate_property(meta_predicate, Module, Name, Arity, MetaPredicateTerm) :- '$meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm). diff --git a/src/machine/lib_machine.rs b/src/machine/lib_machine.rs index 050c883b..1eec92b8 100644 --- a/src/machine/lib_machine.rs +++ b/src/machine/lib_machine.rs @@ -1,12 +1,29 @@ use std::collections::HashSet; -use super::{Machine, MachineConfig, QueryResult, QueryResolution, QueryResolutionLine, Atom}; +use super::{ + Machine, MachineConfig, QueryResult, QueryResolutionLine, + Atom, AtomCell, HeapCellValue, HeapCellValueTag, + streams::Stream +}; impl Machine { pub fn new_lib() -> Self { Machine::new(MachineConfig::in_memory().with_toplevel(include_str!("../lib_toplevel.pl"))) } + pub fn load_module_string(&mut self, module_name: &str, program: String) { + let stream = Stream::from_owned_string(program, &mut self.machine_st.arena); + self.load_file(module_name, stream); + } + + pub fn consult_module_string(&mut self, module_name: &str, program: String) { + let stream = Stream::from_owned_string(program, &mut self.machine_st.arena); + self.machine_st.registers[1] = stream_as_cell!(stream); + self.machine_st.registers[2] = atom_as_cell!(self.machine_st.atom_tbl.build_with(module_name)); + + self.run_module_predicate(atom!("loader"), (atom!("consult_stream"), 2)); + } + pub fn run_query(&mut self, query: String) -> QueryResult { self.set_user_input(query); self.run_top_level(atom!("$toplevel"), (atom!("run_input_once"), 0)); @@ -42,7 +59,7 @@ impl Machine { #[cfg(test)] mod tests { use super::*; - use crate::machine::{QueryMatch, Value}; + use crate::machine::{QueryMatch, Value, QueryResolution}; #[test] fn programatic_query() { @@ -145,4 +162,64 @@ mod tests { ])) ); } + + + #[test] + fn consult() { + let mut machine = Machine::new_lib(); + + machine.consult_module_string( + "facts", + String::from( + r#" + triple("a", "p1", "b"). + triple("a", "p2", "b"). + "#, + ), + ); + + let query = String::from(r#"triple("a",P,"b")."#); + let output = machine.run_query(query); + assert_eq!( + output, + Ok(QueryResolution::Matches(vec![ + QueryMatch::from(btreemap! { + "P" => Value::from("p1"), + }), + QueryMatch::from(btreemap! { + "P" => Value::from("p2"), + }), + ])) + ); + + assert_eq!( + machine.run_query(String::from(r#"triple("a","p1","b")."#)), + Ok(QueryResolution::True) + ); + + assert_eq!( + machine.run_query(String::from(r#"triple("x","y","z")."#)), + Ok(QueryResolution::False) + ); + + machine.consult_module_string( + "facts", + String::from( + r#" + triple("a", "new", "b"). + "#, + ), + ); + + assert_eq!( + machine.run_query(String::from(r#"triple("a","p1","b")."#)), + Ok(QueryResolution::False) + ); + + assert_eq!( + machine.run_query(String::from(r#"triple("a","new","b")."#)), + Ok(QueryResolution::True) + ); + + } } diff --git a/src/machine/mod.rs b/src/machine/mod.rs index 6a319597..c77272c9 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -318,11 +318,6 @@ impl Machine { String::from_utf8(output_bytes).unwrap() } - pub fn load_module_string(&mut self, module_name: &str, program: String) { - let stream = Stream::from_owned_string(program, &mut self.machine_st.arena); - self.load_file(module_name, stream); - } - pub(crate) fn configure_modules(&mut self) { fn update_call_n_indices(loader: &Module, target_code_dir: &mut CodeDir, arena: &mut Arena) { for arity in 1..66 { -- 2.54.0