implement dynamic, multifile, and discontiguous properties and callable type checking for predicate_property/2
This commit is contained in:
@@ -400,6 +400,12 @@ impl SystemClauseType {
|
|||||||
clause_name!("$cpp_meta_predicate_property"),
|
clause_name!("$cpp_meta_predicate_property"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) =>
|
&SystemClauseType::REPL(REPLCodePtr::BuiltInProperty) =>
|
||||||
clause_name!("$cpp_built_in_property"),
|
clause_name!("$cpp_built_in_property"),
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::DynamicProperty) =>
|
||||||
|
clause_name!("$cpp_dynamic_property"),
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::MultifileProperty) =>
|
||||||
|
clause_name!("$cpp_multifile_property"),
|
||||||
|
&SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty) =>
|
||||||
|
clause_name!("$cpp_discontiguous_property"),
|
||||||
&SystemClauseType::REPL(REPLCodePtr::CompilePendingPredicates) =>
|
&SystemClauseType::REPL(REPLCodePtr::CompilePendingPredicates) =>
|
||||||
clause_name!("$compile_pending_predicates"),
|
clause_name!("$compile_pending_predicates"),
|
||||||
&SystemClauseType::Close => clause_name!("$close"),
|
&SystemClauseType::Close => clause_name!("$close"),
|
||||||
@@ -773,6 +779,9 @@ impl SystemClauseType {
|
|||||||
("$prolog_lc_stream", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream)),
|
("$prolog_lc_stream", 1) => Some(SystemClauseType::REPL(REPLCodePtr::LoadContextStream)),
|
||||||
("$cpp_meta_predicate_property", 4) => Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty)),
|
("$cpp_meta_predicate_property", 4) => Some(SystemClauseType::REPL(REPLCodePtr::MetaPredicateProperty)),
|
||||||
("$cpp_built_in_property", 2) => Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty)),
|
("$cpp_built_in_property", 2) => Some(SystemClauseType::REPL(REPLCodePtr::BuiltInProperty)),
|
||||||
|
("$cpp_dynamic_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DynamicProperty)),
|
||||||
|
("$cpp_multifile_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::MultifileProperty)),
|
||||||
|
("$cpp_discontiguous_property", 3) => Some(SystemClauseType::REPL(REPLCodePtr::DiscontiguousProperty)),
|
||||||
("$compile_pending_predicates", 1) => Some(SystemClauseType::REPL(REPLCodePtr::CompilePendingPredicates)),
|
("$compile_pending_predicates", 1) => Some(SystemClauseType::REPL(REPLCodePtr::CompilePendingPredicates)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,6 +336,13 @@ check_predicate_property(meta_predicate, Module, Name, Arity, MetaPredicateTerm)
|
|||||||
'$cpp_meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm).
|
'$cpp_meta_predicate_property'(Module, Name, Arity, MetaPredicateTerm).
|
||||||
check_predicate_property(built_in, _, Name, Arity, built_in) :-
|
check_predicate_property(built_in, _, Name, Arity, built_in) :-
|
||||||
'$cpp_built_in_property'(Name, Arity).
|
'$cpp_built_in_property'(Name, Arity).
|
||||||
|
check_predicate_property(dynamic, Module, Name, Arity, dynamic) :-
|
||||||
|
'$cpp_dynamic_property'(Module, Name, Arity).
|
||||||
|
check_predicate_property(multifile, Module, Name, Arity, multifile) :-
|
||||||
|
'$cpp_multifile_property'(Module, Name, Arity).
|
||||||
|
check_predicate_property(discontiguous, Module, Name, Arity, multifile) :-
|
||||||
|
'$cpp_discontiguous_property'(Module, Name, Arity).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extract_predicate_property(Property, PropertyType) :-
|
extract_predicate_property(Property, PropertyType) :-
|
||||||
@@ -356,12 +363,20 @@ predicate_property(Callable, Property) :-
|
|||||||
; Callable =.. [(:), Module, Callable0],
|
; Callable =.. [(:), Module, Callable0],
|
||||||
atom(Module) ->
|
atom(Module) ->
|
||||||
functor(Callable0, Name, Arity),
|
functor(Callable0, Name, Arity),
|
||||||
|
( atom(Name),
|
||||||
|
Name \== [] ->
|
||||||
extract_predicate_property(Property, PropertyType),
|
extract_predicate_property(Property, PropertyType),
|
||||||
check_predicate_property(PropertyType, Module, Name, Arity, Property)
|
check_predicate_property(PropertyType, Module, Name, Arity, Property)
|
||||||
|
; type_error(callable, Callable0, predicate_property/2)
|
||||||
|
)
|
||||||
; functor(Callable, Name, Arity),
|
; functor(Callable, Name, Arity),
|
||||||
|
( atom(Name),
|
||||||
|
Name \== [] ->
|
||||||
extract_predicate_property(Property, PropertyType),
|
extract_predicate_property(Property, PropertyType),
|
||||||
load_context(Module),
|
load_context(Module),
|
||||||
check_predicate_property(PropertyType, Module, Name, Arity, Property)
|
check_predicate_property(PropertyType, Module, Name, Arity, Property)
|
||||||
|
; type_error(callable, Callable, predicate_property/2)
|
||||||
|
)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -549,6 +549,7 @@ impl<'a> Drop for LoadState<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: necessary? unnecessary?
|
// TODO: necessary? unnecessary?
|
||||||
// self.wam.code_repo.code.truncate(self.retraction_info.orig_code_extent);
|
// self.wam.code_repo.code.truncate(self.retraction_info.orig_code_extent);
|
||||||
}
|
}
|
||||||
@@ -1543,6 +1544,108 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate)
|
||||||
|
fn dynamic_property(&mut self) {
|
||||||
|
let module_name = atom_from!(
|
||||||
|
self.machine_st,
|
||||||
|
self.machine_st.store(self.machine_st.deref(
|
||||||
|
self.machine_st[temp_v!(1)]
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
let key =
|
||||||
|
self.machine_st.read_predicate_key(
|
||||||
|
self.machine_st[temp_v!(2)],
|
||||||
|
self.machine_st[temp_v!(3)],
|
||||||
|
);
|
||||||
|
|
||||||
|
let compilation_target =
|
||||||
|
match module_name.as_str() {
|
||||||
|
"user" => CompilationTarget::User,
|
||||||
|
_ => CompilationTarget::Module(module_name),
|
||||||
|
};
|
||||||
|
|
||||||
|
match self.indices.get_predicate_skeleton(
|
||||||
|
&compilation_target,
|
||||||
|
&key,
|
||||||
|
) {
|
||||||
|
Some(skeleton) => {
|
||||||
|
self.machine_st.fail = !skeleton.is_dynamic;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.machine_st.fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate)
|
||||||
|
fn multifile_property(&mut self) {
|
||||||
|
let module_name = atom_from!(
|
||||||
|
self.machine_st,
|
||||||
|
self.machine_st.store(self.machine_st.deref(
|
||||||
|
self.machine_st[temp_v!(1)]
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
let key =
|
||||||
|
self.machine_st.read_predicate_key(
|
||||||
|
self.machine_st[temp_v!(2)],
|
||||||
|
self.machine_st[temp_v!(3)],
|
||||||
|
);
|
||||||
|
|
||||||
|
let compilation_target =
|
||||||
|
match module_name.as_str() {
|
||||||
|
"user" => CompilationTarget::User,
|
||||||
|
_ => CompilationTarget::Module(module_name),
|
||||||
|
};
|
||||||
|
|
||||||
|
match self.indices.get_predicate_skeleton(
|
||||||
|
&compilation_target,
|
||||||
|
&key,
|
||||||
|
) {
|
||||||
|
Some(skeleton) => {
|
||||||
|
self.machine_st.fail = !skeleton.is_multifile;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.machine_st.fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate)
|
||||||
|
fn discontiguous_property(&mut self) {
|
||||||
|
let module_name = atom_from!(
|
||||||
|
self.machine_st,
|
||||||
|
self.machine_st.store(self.machine_st.deref(
|
||||||
|
self.machine_st[temp_v!(1)]
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
let key =
|
||||||
|
self.machine_st.read_predicate_key(
|
||||||
|
self.machine_st[temp_v!(2)],
|
||||||
|
self.machine_st[temp_v!(3)],
|
||||||
|
);
|
||||||
|
|
||||||
|
let compilation_target =
|
||||||
|
match module_name.as_str() {
|
||||||
|
"user" => CompilationTarget::User,
|
||||||
|
_ => CompilationTarget::Module(module_name),
|
||||||
|
};
|
||||||
|
|
||||||
|
match self.indices.get_predicate_skeleton(
|
||||||
|
&compilation_target,
|
||||||
|
&key,
|
||||||
|
) {
|
||||||
|
Some(skeleton) => {
|
||||||
|
self.machine_st.fail = !skeleton.is_discontiguous;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.machine_st.fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate)
|
pub(crate)
|
||||||
fn builtin_property(&mut self) {
|
fn builtin_property(&mut self) {
|
||||||
let key =
|
let key =
|
||||||
|
|||||||
@@ -505,7 +505,6 @@ pub enum REPLCodePtr {
|
|||||||
AddDynamicPredicate,
|
AddDynamicPredicate,
|
||||||
AddGoalExpansionClause,
|
AddGoalExpansionClause,
|
||||||
AddTermExpansionClause,
|
AddTermExpansionClause,
|
||||||
BuiltInProperty,
|
|
||||||
ClauseToEvacuable,
|
ClauseToEvacuable,
|
||||||
ConcludeLoad,
|
ConcludeLoad,
|
||||||
DeclareModule,
|
DeclareModule,
|
||||||
@@ -520,7 +519,11 @@ pub enum REPLCodePtr {
|
|||||||
PushLoadContext,
|
PushLoadContext,
|
||||||
PushLoadStatePayload,
|
PushLoadStatePayload,
|
||||||
UseModule,
|
UseModule,
|
||||||
|
BuiltInProperty,
|
||||||
MetaPredicateProperty,
|
MetaPredicateProperty,
|
||||||
|
MultifileProperty,
|
||||||
|
DiscontiguousProperty,
|
||||||
|
DynamicProperty,
|
||||||
CompilePendingPredicates,
|
CompilePendingPredicates,
|
||||||
UserAsserta,
|
UserAsserta,
|
||||||
UserAssertz,
|
UserAssertz,
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ impl Machine {
|
|||||||
for arity in 1 .. 66 {
|
for arity in 1 .. 66 {
|
||||||
let key = (clause_name!("call"), arity);
|
let key = (clause_name!("call"), arity);
|
||||||
|
|
||||||
match loader.code_dir.get(&key).cloned() {
|
match loader.code_dir.get(&key) {
|
||||||
Some(src_code_index) => {
|
Some(src_code_index) => {
|
||||||
let target_code_index = target_module.code_dir
|
let target_code_index = target_module.code_dir
|
||||||
.entry(key.clone())
|
.entry(key.clone())
|
||||||
@@ -482,6 +482,15 @@ impl Machine {
|
|||||||
REPLCodePtr::BuiltInProperty => {
|
REPLCodePtr::BuiltInProperty => {
|
||||||
self.builtin_property();
|
self.builtin_property();
|
||||||
}
|
}
|
||||||
|
REPLCodePtr::MultifileProperty => {
|
||||||
|
self.multifile_property();
|
||||||
|
}
|
||||||
|
REPLCodePtr::DiscontiguousProperty => {
|
||||||
|
self.discontiguous_property();
|
||||||
|
}
|
||||||
|
REPLCodePtr::DynamicProperty => {
|
||||||
|
self.dynamic_property();
|
||||||
|
}
|
||||||
REPLCodePtr::CompilePendingPredicates => {
|
REPLCodePtr::CompilePendingPredicates => {
|
||||||
self.compile_pending_predicates();
|
self.compile_pending_predicates();
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/write.rs
10
src/write.rs
@@ -26,8 +26,6 @@ impl fmt::Display for REPLCodePtr {
|
|||||||
write!(f, "REPLCodePtr::AddGoalExpansionClause"),
|
write!(f, "REPLCodePtr::AddGoalExpansionClause"),
|
||||||
REPLCodePtr::AddTermExpansionClause =>
|
REPLCodePtr::AddTermExpansionClause =>
|
||||||
write!(f, "REPLCodePtr::AddTermExpansionClause"),
|
write!(f, "REPLCodePtr::AddTermExpansionClause"),
|
||||||
REPLCodePtr::BuiltInProperty =>
|
|
||||||
write!(f, "REPLCodePtr::BuiltInProperty"),
|
|
||||||
REPLCodePtr::UserAssertz =>
|
REPLCodePtr::UserAssertz =>
|
||||||
write!(f, "REPLCodePtr::UserAssertz"),
|
write!(f, "REPLCodePtr::UserAssertz"),
|
||||||
REPLCodePtr::UserAsserta =>
|
REPLCodePtr::UserAsserta =>
|
||||||
@@ -64,6 +62,14 @@ impl fmt::Display for REPLCodePtr {
|
|||||||
write!(f, "REPLCodePtr::UseModule"),
|
write!(f, "REPLCodePtr::UseModule"),
|
||||||
REPLCodePtr::MetaPredicateProperty =>
|
REPLCodePtr::MetaPredicateProperty =>
|
||||||
write!(f, "REPLCodePtr::MetaPredicateProperty"),
|
write!(f, "REPLCodePtr::MetaPredicateProperty"),
|
||||||
|
REPLCodePtr::BuiltInProperty =>
|
||||||
|
write!(f, "REPLCodePtr::BuiltInProperty"),
|
||||||
|
REPLCodePtr::DynamicProperty =>
|
||||||
|
write!(f, "REPLCodePtr::DynamicProperty"),
|
||||||
|
REPLCodePtr::MultifileProperty =>
|
||||||
|
write!(f, "REPLCodePtr::MultifileProperty"),
|
||||||
|
REPLCodePtr::DiscontiguousProperty =>
|
||||||
|
write!(f, "REPLCodePtr::DiscontiguousProperty"),
|
||||||
REPLCodePtr::CompilePendingPredicates =>
|
REPLCodePtr::CompilePendingPredicates =>
|
||||||
write!(f, "REPLCodePtr::CompilePendingPredicates"),
|
write!(f, "REPLCodePtr::CompilePendingPredicates"),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user