correct project_attributes, correct compare_term_test and eq_test, polish attribute_goals/2

This commit is contained in:
Mark Thom
2019-02-14 21:59:24 -07:00
parent 6b879467f3
commit 9abe70113a
9 changed files with 127 additions and 60 deletions

View File

@@ -3,7 +3,7 @@ driver(Vars, Values) :-
'$redo_attr_var_bindings', % the bindings list is emptied here.
!,
call_goals(ListOfListsOfGoalLists),
'$restore_p_from_sfcp'.
'$return_from_verify_attr'.
iterate([Var|VarBindings], [Value|ValueBindings], [ListOfGoalLists | ListsCubed]) :-
'$get_attr_list'(Var, Ls),

View File

@@ -2,6 +2,7 @@ use prolog::heap_iter::*;
use prolog::machine::*;
use std::collections::HashSet;
use std::collections::hash_set::IntoIter;
pub static VERIFY_ATTRS: &str = include_str!("attributed_variables.pl");
pub static PROJECT_ATTRS: &str = include_str!("project_attributes.pl");
@@ -9,15 +10,17 @@ pub static PROJECT_ATTRS: &str = include_str!("project_attributes.pl");
pub(super) type Bindings = Vec<(usize, Addr)>;
pub(super) struct AttrVarInitializer {
pub(super) attribute_goals: Vec<Addr>,
pub(super) bindings: Bindings,
pub(super) cp: LocalCodePtr,
pub(super) verify_attrs_loc: usize,
pub(super) project_attrs_loc: usize
pub(super) project_attrs_loc: usize,
}
impl AttrVarInitializer {
pub(super) fn new(verify_attrs_loc: usize, project_attrs_loc: usize) -> Self {
AttrVarInitializer {
attribute_goals: vec![],
bindings: vec![],
cp: LocalCodePtr::default(),
verify_attrs_loc,
@@ -70,33 +73,37 @@ impl MachineState {
pub(super)
fn verify_attributes(&mut self)
{
/* STEP 1: Undo bindings in machine.
STEP 2: Write the list of bindings to two lists in the heap, one for vars, one for values.
STEP 3: Pass the addresses of the lists to iterate in the attr_vars special form.
Call verify_attributes/3 wherever applicable.
STEP 4: Redo the bindings.
STEP 5: Call the goals.
STEP 6: Pop the top of AttrVarInitializer::cp_stack to self.p.
STEP 7: Swap the AttrVarInitializer's Registers back for the machine's Registers.
*/
// STEP 1.
for (h, _) in &self.attr_var_init.bindings {
self.heap[*h] = HeapCellValue::Addr(Addr::AttrVar(*h));
}
// STEP 2.
let (var_list_addr, value_list_addr) = self.populate_var_and_value_lists();
// STEP 3.
self[temp_v!(1)] = var_list_addr;
self[temp_v!(2)] = value_list_addr;
}
fn gather_attr_vars_created_since(&mut self, h: usize) -> IntoIter<Addr> {
let mut attr_vars = HashSet::new();
for i in h .. self.heap.len() {
let addr = self.heap[i].as_addr(i);
match self.store(self.deref(addr)) {
Addr::AttrVar(h) => {
attr_vars.insert(Addr::AttrVar(h));
},
_ => {}
}
}
attr_vars.into_iter()
}
fn populate_project_attr_lists(&mut self, var_dict: &HeapVarDict) -> (Addr, Addr)
{
let mut query_vars = HashSet::new();
let mut attr_vars = HashSet::new();
let attr_vars = self.gather_attr_vars_created_since(0);
for (_, addr) in var_dict {
let iter = HCPreOrderIterator::new(&self, addr.clone());
@@ -109,16 +116,13 @@ impl MachineState {
HeapCellValue::Addr(Addr::StackCell(fr, sc)) => {
query_vars.insert(Addr::StackCell(fr, sc));
},
HeapCellValue::Addr(Addr::AttrVar(h)) => {
attr_vars.insert(Addr::AttrVar(h));
},
_ => {}
};
}
}
let query_var_list = Addr::HeapCell(self.heap.to_list(query_vars.into_iter()));
let attr_var_list = Addr::HeapCell(self.heap.to_list(attr_vars.into_iter()));
let attr_var_list = Addr::HeapCell(self.heap.to_list(attr_vars));
(query_var_list, attr_var_list)
}
@@ -150,9 +154,37 @@ impl MachineState {
self.b0 = self.b;
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
}
fn print_attribute_goals(&mut self, var_dict: &HeapVarDict)
{
let attr_goals = mem::replace(&mut self.attr_var_init.attribute_goals, vec![]);
if attr_goals.is_empty() {
return;
}
let mut output = PrinterOutputter::new();
for goal_addr in attr_goals {
let mut printer = HCPrinter::from_heap_locs(&self, output, var_dict);
printer.see_all_locs();
printer.numbervars = false;
printer.quoted = true;
output = printer.print(goal_addr);
output.append(", ");
}
// cut trailing ", "
let output_len = output.len();
output.truncate(output_len - 2);
println!("\r\n{}\r", output.result());
}
}
impl Machine {
impl Machine {
pub
fn attribute_goals(&mut self, var_dict: &HeapVarDict)
{
@@ -166,5 +198,7 @@ impl Machine {
self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
self.machine_st.query_stepper(&mut self.indices, &mut self.policies, &mut self.code_repo);
self.machine_st.print_attribute_goals(var_dict);
}
}

View File

@@ -149,7 +149,7 @@ impl MachineState {
}
pub(super)
fn print_var_eq<Outputter>(&self, var: Rc<Var>, addr: Addr, var_dir: &HeapVarDict,
fn print_var_eq<Outputter>(&self, var: Rc<Var>, addr: Addr, var_dict: &HeapVarDict,
mut output: Outputter)
-> Outputter
where Outputter: HCValueOutputter
@@ -161,7 +161,7 @@ impl MachineState {
output.append(var.as_str());
output.append(" = ");
let mut printer = HCPrinter::from_heap_locs(&self, output, var_dir);
let mut printer = HCPrinter::from_heap_locs(&self, output, var_dict);
printer.numbervars = false;
printer.quoted = true;
@@ -178,11 +178,11 @@ impl MachineState {
}
pub(super)
fn print_exception<Outputter>(&self, addr: Addr, var_dir: &HeapVarDict, output: Outputter)
fn print_exception<Outputter>(&self, addr: Addr, var_dict: &HeapVarDict, output: Outputter)
-> Outputter
where Outputter: HCValueOutputter
{
let printer = HCPrinter::from_heap_locs(&self, output, var_dir);
let printer = HCPrinter::from_heap_locs(&self, output, var_dict);
printer.print(addr)
}
@@ -1562,9 +1562,9 @@ impl MachineState {
let a1 = self[temp_v!(1)].clone();
let a2 = self[temp_v!(2)].clone();
let iter = self.zipped_acyclic_pre_order_iter(a1, a2);
let mut iter = self.zipped_acyclic_pre_order_iter(a1, a2);
for (v1, v2) in iter {
while let Some((v1, v2)) = iter.next() {
match (v1, v2) {
(HeapCellValue::NamedStr(ar1, n1, _), HeapCellValue::NamedStr(ar2, n2, _)) =>
if ar1 != ar2 || n1 != n2 {
@@ -1580,13 +1580,14 @@ impl MachineState {
}
}
false
// did the two iterators expire at the same step?
iter.first_to_expire != Ordering::Equal
}
pub(super) fn compare_term_test(&self, a1: &Addr, a2: &Addr) -> Ordering {
let iter = self.zipped_acyclic_pre_order_iter(a1.clone(), a2.clone());
let mut iter = self.zipped_acyclic_pre_order_iter(a1.clone(), a2.clone());
for (v1, v2) in iter {
while let Some((v1, v2)) = iter.next() {
match (v1, v2) {
(HeapCellValue::Addr(Addr::Lis(_)), HeapCellValue::Addr(Addr::Con(Constant::String(_))))
| (HeapCellValue::Addr(Addr::Con(Constant::String(_))), HeapCellValue::Addr(Addr::Lis(_)))
@@ -1742,7 +1743,7 @@ impl MachineState {
}
};
Ordering::Equal
iter.first_to_expire
}
pub(super) fn reset_block(&mut self, addr: Addr) {

View File

@@ -4,7 +4,23 @@ driver(QueryVars, AttrVars) :-
call_project_attributes(Modules, QueryVars, AttrVars),
call_attribute_goals(Modules, QueryVars),
call_attribute_goals(Modules, AttrVars),
'$deallocate'.
'$return_from_attribute_goals'.
enqueue_goal(Goals0) :-
nonvar(Goals0), Goals0 = [Goal | Goals], !,
enqueue_goals(Goals0). % enqueue lists of goals separately.
enqueue_goal(Goal) :-
nonvar(Goal),
'$enqueue_attribute_goal'(Goal). % enqueue the goal for printing to the toplevel.
enqueue_goals(Goals0) :-
nonvar(Goals0),
Goals0 = [Goal | Goals],
nonvar(Goal),
!,
'$enqueue_attribute_goal'(Goal),
enqueue_goals(Goals).
enqueue_goals(_).
call_project_attributes([], _, _).
call_project_attributes([Module|Modules], QueryVars, AttrVars) :-
@@ -25,7 +41,7 @@ call_goals([AttrVar|AttrVars], Module) :-
( catch(Module:attribute_goals(AttrVar, Goal),
error(evaluation_error((Module:attribute_goals)/2), attribute_goals/2),
true),
nonvar(Goal) -> nl, writeq(Goal)
nonvar(Goal) -> enqueue_goal(Goal)
; true
),
call_goals(AttrVars, Module).

View File

@@ -203,11 +203,7 @@ impl MachineState {
Addr::Con(Constant::Usize(old_b)) if self.b <= old_b + 2 => {},
_ => self.fail = true
};
},
&SystemClauseType::Deallocate => {
self.deallocate();
return Ok(());
},
},
&SystemClauseType::DeleteAttribute => {
let ls0 = self.store(self.deref(self[temp_v!(1)].clone()));
@@ -264,6 +260,10 @@ impl MachineState {
}
};
},
&SystemClauseType::EnqueueAttributeGoal => {
let addr = self[temp_v!(1)].clone();
self.attr_var_init.attribute_goals.push(addr);
},
&SystemClauseType::ExpandGoal => {
self.p = CodePtr::Local(LocalCodePtr::UserGoalExpansion(0));
return Ok(());
@@ -453,7 +453,12 @@ impl MachineState {
None => panic!("remove_inference_counter: requires \\
CWILCallPolicy.")
},
&SystemClauseType::RestoreCodePtrFromSpecialFormCP => {
&SystemClauseType::ReturnFromAttributeGoals => {
self.deallocate();
self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
return Ok(());
},
&SystemClauseType::ReturnFromVerifyAttr => {
let e = self.e;
let frame_len = self.and_stack[e].len();