Merge branch 'master' into library-use-case
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
integer_si/1,
|
integer_si/1,
|
||||||
atomic_si/1,
|
atomic_si/1,
|
||||||
list_si/1,
|
list_si/1,
|
||||||
|
character_si/1,
|
||||||
chars_si/1,
|
chars_si/1,
|
||||||
dif_si/2]).
|
dif_si/2]).
|
||||||
|
|
||||||
@@ -62,9 +63,29 @@ list_si(L0) :-
|
|||||||
; throw(error(instantiation_error, list_si/1))
|
; throw(error(instantiation_error, list_si/1))
|
||||||
).
|
).
|
||||||
|
|
||||||
chars_si(Cs) :-
|
character_si(Ch) :-
|
||||||
list_si(Cs),
|
functor(Ch,Ch,0),
|
||||||
'$is_partial_string'(Cs).
|
atom(Ch),
|
||||||
|
atom_length(Ch,1).
|
||||||
|
|
||||||
|
chars_si(Chs0) :-
|
||||||
|
'$skip_max_list'(_,_, Chs0,Chs),
|
||||||
|
( nonvar(Chs) -> Chs == [] ; true ), % fails for infinite lists too
|
||||||
|
failnochars(Chs0, Uninstantiated),
|
||||||
|
( nonvar(Uninstantiated)
|
||||||
|
-> throw(error(instantiation_error, chars_si/1))
|
||||||
|
; true
|
||||||
|
).
|
||||||
|
|
||||||
|
failnochars(Chs0, U) :-
|
||||||
|
( var(Chs0) -> U = true
|
||||||
|
; Chs0 == [] -> true
|
||||||
|
; Chs0 = [Ch|Chs1],
|
||||||
|
( nonvar(Ch) -> atom(Ch), atom_length(Ch,1)
|
||||||
|
; U = true
|
||||||
|
),
|
||||||
|
failnochars(Chs1, U)
|
||||||
|
).
|
||||||
|
|
||||||
dif_si(X, Y) :-
|
dif_si(X, Y) :-
|
||||||
X \== Y,
|
X \== Y,
|
||||||
|
|||||||
@@ -1258,7 +1258,7 @@ fn print_overwrite_warning(
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Warning: overwriting {}/{}", key.0.as_str(), key.1);
|
println!("Warning: overwriting {}/{} because the clauses are discontiguous", key.0.as_str(), key.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
||||||
@@ -2220,7 +2220,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
|
|
||||||
let payload_compilation_target = self.payload.compilation_target;
|
let payload_compilation_target = self.payload.compilation_target;
|
||||||
|
|
||||||
let local_predicate_info = self
|
let mut local_predicate_info = self
|
||||||
.wam_prelude
|
.wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.get_local_predicate_skeleton(
|
.get_local_predicate_skeleton(
|
||||||
@@ -2242,6 +2242,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let is_cross_module_clause =
|
let is_cross_module_clause =
|
||||||
payload_compilation_target != self.payload.predicates.compilation_target;
|
payload_compilation_target != self.payload.predicates.compilation_target;
|
||||||
|
|
||||||
|
local_predicate_info.is_discontiguous = predicate_info.is_discontiguous;
|
||||||
|
|
||||||
if local_predicate_info.must_retract_local_clauses(is_cross_module_clause) {
|
if local_predicate_info.must_retract_local_clauses(is_cross_module_clause) {
|
||||||
self.retract_local_clauses(&key, predicate_info.is_dynamic);
|
self.retract_local_clauses(&key, predicate_info.is_dynamic);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -530,7 +530,36 @@ impl VariableClassifier {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut add_chunk = |classifier: &mut Self, name: Atom, terms: Vec<Term>| {
|
||||||
|
if update_chunk_data(classifier, name, terms.len()) {
|
||||||
|
build_stack.add_chunk();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (arg_c, term) in terms.iter().enumerate() {
|
||||||
|
classifier.probe_body_term(arg_c + 1, terms.len(), term);
|
||||||
|
}
|
||||||
|
|
||||||
|
build_stack.push_chunk_term(
|
||||||
|
clause_to_query_term(
|
||||||
|
loader,
|
||||||
|
name,
|
||||||
|
terms,
|
||||||
|
classifier.call_policy,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
match term {
|
match term {
|
||||||
|
Term::Clause(_, name @ (atom!("->") | atom!(";") | atom!(",")), mut terms) if terms.len() == 3 => {
|
||||||
|
if let Some(last_arg) = terms.last() {
|
||||||
|
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
|
||||||
|
terms.pop();
|
||||||
|
state_stack.push(TraversalState::Term(Term::Clause(Cell::default(), name, terms)));
|
||||||
|
} else {
|
||||||
|
add_chunk(self, name, terms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Term::Clause(_, atom!(","), mut terms) if terms.len() == 2 => {
|
Term::Clause(_, atom!(","), mut terms) if terms.len() == 2 => {
|
||||||
let tail = terms.pop().unwrap();
|
let tail = terms.pop().unwrap();
|
||||||
let head = terms.pop().unwrap();
|
let head = terms.pop().unwrap();
|
||||||
@@ -700,22 +729,7 @@ impl VariableClassifier {
|
|||||||
self.call_policy = CallPolicy::Counted;
|
self.call_policy = CallPolicy::Counted;
|
||||||
}
|
}
|
||||||
Term::Clause(_, name, terms) => {
|
Term::Clause(_, name, terms) => {
|
||||||
if update_chunk_data(self, name, terms.len()) {
|
add_chunk(self, name, terms);
|
||||||
build_stack.add_chunk();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (arg_c, term) in terms.iter().enumerate() {
|
|
||||||
self.probe_body_term(arg_c + 1, terms.len(), term);
|
|
||||||
}
|
|
||||||
|
|
||||||
build_stack.push_chunk_term(
|
|
||||||
clause_to_query_term(
|
|
||||||
loader,
|
|
||||||
name,
|
|
||||||
terms,
|
|
||||||
self.call_policy,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
var @ Term::Var(..) => {
|
var @ Term::Var(..) => {
|
||||||
if update_chunk_data(self, atom!("call"), 1) {
|
if update_chunk_data(self, atom!("call"), 1) {
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ use std::ops::{Deref, DerefMut};
|
|||||||
* loader.pl does a few high-level things more easily handled from
|
* loader.pl does a few high-level things more easily handled from
|
||||||
* Prolog that are not supported (or needed) during bootstrapping:
|
* Prolog that are not supported (or needed) during bootstrapping:
|
||||||
* term and goal expansion, loading modules from different streams,
|
* term and goal expansion, loading modules from different streams,
|
||||||
* verifying certain kinds of declarations, perhaps (in the future?)
|
* and verifying certain kinds of declarations.
|
||||||
* compiling inline disjunctions.
|
|
||||||
*
|
*
|
||||||
* Since the loader can operate incrementally, it uses an intermittent
|
* Since the loader can operate incrementally, it uses an intermittent
|
||||||
* structure to rebuild the loader between invocations. Preprocessor
|
* structure to rebuild the loader between invocations. Preprocessor
|
||||||
@@ -1279,6 +1278,17 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
name: Atom,
|
name: Atom,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
|
let key = (name, arity);
|
||||||
|
|
||||||
|
let predicate_info = self
|
||||||
|
.wam_prelude
|
||||||
|
.indices
|
||||||
|
.get_predicate_skeleton(&self.payload.predicates.compilation_target, &key)
|
||||||
|
.map(|skeleton| skeleton.predicate_info())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
self.retract_local_clauses(&key, predicate_info.is_dynamic);
|
||||||
|
|
||||||
self.add_extensible_predicate_declaration(
|
self.add_extensible_predicate_declaration(
|
||||||
compilation_target,
|
compilation_target,
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use crate::read::devour_whitespace;
|
|||||||
|
|
||||||
use crate::predicate_queue;
|
use crate::predicate_queue;
|
||||||
|
|
||||||
|
use fxhash::FxBuildHasher;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
@@ -19,7 +20,7 @@ pub struct LoadStatePayload<TS> {
|
|||||||
pub(super) compilation_target: CompilationTarget,
|
pub(super) compilation_target: CompilationTarget,
|
||||||
pub(super) retraction_info: RetractionInfo,
|
pub(super) retraction_info: RetractionInfo,
|
||||||
pub(super) module_op_exports: ModuleOpExports,
|
pub(super) module_op_exports: ModuleOpExports,
|
||||||
pub(super) non_counted_bt_preds: IndexSet<PredicateKey>,
|
pub(super) non_counted_bt_preds: IndexSet<PredicateKey, FxBuildHasher>,
|
||||||
pub(super) predicates: PredicateQueue,
|
pub(super) predicates: PredicateQueue,
|
||||||
pub(super) clause_clauses: Vec<(Term, Term)>,
|
pub(super) clause_clauses: Vec<(Term, Term)>,
|
||||||
}
|
}
|
||||||
@@ -97,7 +98,7 @@ impl<TS> LoadStatePayload<TS> {
|
|||||||
compilation_target: CompilationTarget::default(),
|
compilation_target: CompilationTarget::default(),
|
||||||
retraction_info: RetractionInfo::new(code_repo_len),
|
retraction_info: RetractionInfo::new(code_repo_len),
|
||||||
module_op_exports: vec![],
|
module_op_exports: vec![],
|
||||||
non_counted_bt_preds: IndexSet::new(),
|
non_counted_bt_preds: IndexSet::with_hasher(FxBuildHasher::default()),
|
||||||
predicates: predicate_queue![],
|
predicates: predicate_queue![],
|
||||||
clause_clauses: vec![],
|
clause_clauses: vec![],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -830,30 +830,3 @@ pub fn unfold_by_str(mut term: Term, s: Atom) -> Vec<Term> {
|
|||||||
terms.push(term);
|
terms.push(term);
|
||||||
terms
|
terms
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unfold_by_str_ref_once(term: &Term, s: Atom) -> Option<(&Term, &Term)> {
|
|
||||||
if let Term::Clause(_, ref name, ref subterms) = term {
|
|
||||||
if name == &s && subterms.len() == 2 {
|
|
||||||
let fst = &subterms[0];
|
|
||||||
let snd = &subterms[1];
|
|
||||||
|
|
||||||
return Some((fst, snd));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unfold_by_str_ref(mut term: &Term, s: Atom) -> Vec<&Term> {
|
|
||||||
let mut terms = vec![];
|
|
||||||
|
|
||||||
while let Some((fst, snd)) = unfold_by_str_ref_once(&term, s) {
|
|
||||||
terms.push(fst);
|
|
||||||
term = snd;
|
|
||||||
}
|
|
||||||
|
|
||||||
terms.push(term);
|
|
||||||
terms
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user