Add consult that works with streams / strings in library use-case
This commit is contained in:
@@ -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) :-
|
check_predicate_property(meta_predicate, Module, Name, Arity, MetaPredicateTerm) :-
|
||||||
'$meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm).
|
'$meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm).
|
||||||
|
|||||||
@@ -1,12 +1,29 @@
|
|||||||
use std::collections::HashSet;
|
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 {
|
impl Machine {
|
||||||
pub fn new_lib() -> Self {
|
pub fn new_lib() -> Self {
|
||||||
Machine::new(MachineConfig::in_memory().with_toplevel(include_str!("../lib_toplevel.pl")))
|
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 {
|
pub fn run_query(&mut self, query: String) -> QueryResult {
|
||||||
self.set_user_input(query);
|
self.set_user_input(query);
|
||||||
self.run_top_level(atom!("$toplevel"), (atom!("run_input_once"), 0));
|
self.run_top_level(atom!("$toplevel"), (atom!("run_input_once"), 0));
|
||||||
@@ -42,7 +59,7 @@ impl Machine {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::machine::{QueryMatch, Value};
|
use crate::machine::{QueryMatch, Value, QueryResolution};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn programatic_query() {
|
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)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -318,11 +318,6 @@ impl Machine {
|
|||||||
String::from_utf8(output_bytes).unwrap()
|
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) {
|
pub(crate) fn configure_modules(&mut self) {
|
||||||
fn update_call_n_indices(loader: &Module, target_code_dir: &mut CodeDir, arena: &mut Arena) {
|
fn update_call_n_indices(loader: &Module, target_code_dir: &mut CodeDir, arena: &mut Arena) {
|
||||||
for arity in 1..66 {
|
for arity in 1..66 {
|
||||||
|
|||||||
Reference in New Issue
Block a user