From 018b076835fd0044e88ccae48b29367bdb72f317 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Thu, 5 Dec 2019 00:33:46 -0700 Subject: [PATCH] binding attributed variables more eagerly after each implementation of verify_attributes/3 has been called (#248) --- src/prolog/clause_types.rs | 9 ++++--- src/prolog/lib/atts.pl | 21 ++++++++++------ src/prolog/machine/attributed_variables.pl | 3 ++- src/prolog/machine/compile.rs | 3 ++- src/prolog/machine/system_calls.rs | 29 +++++++++++++++++++--- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index e4bae2ae..37f9ada9 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -165,6 +165,7 @@ pub enum SystemClauseType { CallAttributeGoals, CharCode, CharsToNumber, + ClearAttrVarBindings, CloneAttributeGoals, CodesToNumber, CopyTermWithoutAttrVars, @@ -214,7 +215,7 @@ pub enum SystemClauseType { REPL(REPLCodePtr), ReadQueryTerm, ReadTerm, - RedoAttrVarBindings, + RedoAttrVarBinding, RemoveCallPolicyCheck, RemoveInferenceCounter, ResetGlobalVarAtKey, @@ -280,6 +281,7 @@ impl SystemClauseType { &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile) => { clause_name!("$use_qualified_module_from_file") } + &SystemClauseType::ClearAttrVarBindings => clause_name!("$clear_attr_var_bindings"), &SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"), &SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"), &SystemClauseType::DeleteHeadAttribute => clause_name!("$del_attr_head"), @@ -340,7 +342,7 @@ impl SystemClauseType { &SystemClauseType::NumberToChars => clause_name!("$number_to_chars"), &SystemClauseType::NumberToCodes => clause_name!("$number_to_codes"), &SystemClauseType::RawInputReadChar => clause_name!("$raw_input_read_char"), - &SystemClauseType::RedoAttrVarBindings => clause_name!("$redo_attr_var_bindings"), + &SystemClauseType::RedoAttrVarBinding => clause_name!("$redo_attr_var_binding"), &SystemClauseType::RemoveCallPolicyCheck => clause_name!("$remove_call_policy_check"), &SystemClauseType::RemoveInferenceCounter => clause_name!("$remove_inference_counter"), &SystemClauseType::RestoreCutPolicy => clause_name!("$restore_cut_policy"), @@ -395,6 +397,7 @@ impl SystemClauseType { ("$call_attribute_goals", 2) => Some(SystemClauseType::CallAttributeGoals), ("$char_code", 2) => Some(SystemClauseType::CharCode), ("$chars_to_number", 2) => Some(SystemClauseType::CharsToNumber), + ("$clear_attr_var_bindings", 0) => Some(SystemClauseType::ClearAttrVarBindings), ("$clone_attribute_goals", 1) => Some(SystemClauseType::CloneAttributeGoals), ("$codes_to_number", 2) => Some(SystemClauseType::CodesToNumber), ("$copy_term_without_attr_vars", 2) => Some(SystemClauseType::CopyTermWithoutAttrVars), @@ -444,7 +447,7 @@ impl SystemClauseType { ("$number_to_chars", 2) => Some(SystemClauseType::NumberToChars), ("$number_to_codes", 2) => Some(SystemClauseType::NumberToCodes), ("$op", 3) => Some(SystemClauseType::OpDeclaration), - ("$redo_attr_var_bindings", 0) => Some(SystemClauseType::RedoAttrVarBindings), + ("$redo_attr_var_binding", 2) => Some(SystemClauseType::RedoAttrVarBinding), ("$remove_call_policy_check", 1) => Some(SystemClauseType::RemoveCallPolicyCheck), ("$remove_inference_counter", 2) => Some(SystemClauseType::RemoveInferenceCounter), ("$restore_cut_policy", 0) => Some(SystemClauseType::RestoreCutPolicy), diff --git a/src/prolog/lib/atts.pl b/src/prolog/lib/atts.pl index 15d56313..71115639 100644 --- a/src/prolog/lib/atts.pl +++ b/src/prolog/lib/atts.pl @@ -46,7 +46,8 @@ '$get_attr_list'(V, Ls), '$add_to_list'(Ls, V, Attr). '$add_to_list'(Ls, V, Attr) :- - ( var(Ls) -> Ls = [Attr | _], '$enqueue_attr_var'(V) + ( var(Ls) -> + Ls = [Attr | _], '$enqueue_attr_var'(V) ; Ls = [_ | Ls0], '$add_to_list'(Ls0, V, Attr) ). @@ -56,7 +57,8 @@ Ls0 = [Att | Ls1], nonvar(Att), ( Att \= Attr -> '$del_attr_buried'(Ls0, Ls1, V, Attr) - ; '$enqueue_attr_var'(V), '$del_attr_head'(V), '$del_attr'(Ls1, V, Attr) + ; '$enqueue_attr_var'(V), + '$del_attr_head'(V), '$del_attr'(Ls1, V, Attr) ). '$del_attr_step'(Ls1, V, Attr) :- @@ -122,13 +124,18 @@ put_attr(Name, Arity) --> { functor(Attr, Name, Arity), numbervars(Attr, 0, Arity), V = '$VAR'(Arity) }, - [(put_atts(V, +Attr) :- !, functor(Attr, Head, Arity), functor(AttrForm, Head, Arity), - '$get_attr_list'(V, Ls), '$del_attr'(Ls, V, AttrForm), + [(put_atts(V, +Attr) :- !, functor(Attr, Head, Arity), + functor(AttrForm, Head, Arity), + '$get_attr_list'(V, Ls), + '$del_attr'(Ls, V, AttrForm), '$put_attr'(V, Attr)), - (put_atts(V, Attr) :- !, functor(Attr, Head, Arity), functor(AttrForm, Head, Arity), - '$get_attr_list'(V, Ls), '$del_attr'(Ls, V, AttrForm), + (put_atts(V, Attr) :- !, functor(Attr, Head, Arity), + functor(AttrForm, Head, Arity), + '$get_attr_list'(V, Ls), + '$del_attr'(Ls, V, AttrForm), '$put_attr'(V, Attr)), - (put_atts(V, -Attr) :- !, functor(Attr, _, _), '$get_attr_list'(V, Ls), + (put_atts(V, -Attr) :- !, functor(Attr, _, _), + '$get_attr_list'(V, Ls), '$del_attr'(Ls, V, Attr))]. get_attr(Name, Arity) --> diff --git a/src/prolog/machine/attributed_variables.pl b/src/prolog/machine/attributed_variables.pl index 8d896083..01ea8b7d 100644 --- a/src/prolog/machine/attributed_variables.pl +++ b/src/prolog/machine/attributed_variables.pl @@ -1,6 +1,6 @@ driver(Vars, Values) :- iterate(Vars, Values, ListOfListsOfGoalLists), - '$redo_attr_var_bindings', % the bindings list is emptied here. + '$clear_attr_var_bindings', !, call_goals(ListOfListsOfGoalLists), '$return_from_verify_attr'. @@ -8,6 +8,7 @@ driver(Vars, Values) :- iterate([Var|VarBindings], [Value|ValueBindings], [ListOfGoalLists | ListsCubed]) :- '$get_attr_list'(Var, Ls), call_verify_attributes(Ls, Var, Value, ListOfGoalLists), + '$redo_attr_var_binding'(Var, Value), iterate(VarBindings, ValueBindings, ListsCubed). iterate([], [], []). diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index 36c7bf60..f9cf5f8b 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -649,7 +649,8 @@ impl ListingCompiler { let idx = code_dir .entry((name.clone(), arity)) .or_insert(CodeIndex::default()); - set_code_index!(idx, IndexPtr::Index(p), self.get_module_name()); + + set_code_index!(idx, IndexPtr::Index(p), self.get_module_name()); self.localize_self_calls(name, arity, &mut decl_code, p); code.extend(decl_code.into_iter()); diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 22e9c1ea..11eb193e 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -1644,11 +1644,32 @@ impl MachineState { } }; } - &SystemClauseType::RedoAttrVarBindings => { - let bindings = mem::replace(&mut self.attr_var_init.bindings, vec![]); + &SystemClauseType::ClearAttrVarBindings => { + self.attr_var_init.bindings.clear(); + } + &SystemClauseType::RedoAttrVarBinding => { + let var = self.store(self.deref(self[temp_v!(1)].clone())); + let value = self.store(self.deref(self[temp_v!(2)].clone())); + + match var { + Addr::AttrVar(h) => { + if let Addr::AttrVar(h1) = value { + self.heap[h] = HeapCellValue::Addr(Addr::AttrVar(h1)); - for (h, addr) in bindings { - self.heap[h] = HeapCellValue::Addr(addr); + // append h's attributes list to h1's. + let mut l = h1 + 1; + + while let Addr::Lis(l1) = self.store(self.deref(self.heap[l].as_addr(l))) { + l = l1 + 1; + } + + self.heap[l] = HeapCellValue::Addr(Addr::HeapCell(h + 1)); + self.trail(TrailRef::Ref(Ref::HeapCell(l))); + } else { + self.heap[h] = HeapCellValue::Addr(value); + } + } + _ => unreachable!() } } &SystemClauseType::ResetGlobalVarAtKey => { -- 2.54.0