incomplete cut corrections.

This commit is contained in:
Mark Thom
2018-04-07 00:15:34 -06:00
parent 2e65f7243c
commit 5d0674a667
8 changed files with 81 additions and 24 deletions

View File

@@ -13,6 +13,9 @@ pub trait Allocator<'a>
where Target: CompilationTarget<'a>; where Target: CompilationTarget<'a>;
fn mark_non_var<Target>(&mut self, Level, GenContext, &'a Cell<RegType>, &mut Vec<Target>) fn mark_non_var<Target>(&mut self, Level, GenContext, &'a Cell<RegType>, &mut Vec<Target>)
where Target: CompilationTarget<'a>; where Target: CompilationTarget<'a>;
fn mark_reserved_var<Target>(&mut self, Rc<Var>, Level, &'a Cell<VarReg>, GenContext,
&mut Vec<Target>, RegType, bool)
where Target: CompilationTarget<'a>;
fn mark_var<Target>(&mut self, Rc<Var>, Level, &'a Cell<VarReg>, GenContext, &mut Vec<Target>) fn mark_var<Target>(&mut self, Rc<Var>, Level, &'a Cell<VarReg>, GenContext, &mut Vec<Target>)
where Target: CompilationTarget<'a>; where Target: CompilationTarget<'a>;
@@ -52,7 +55,7 @@ pub trait Allocator<'a>
} }
fn is_unbound(&self, var: Rc<Var>) -> bool { fn is_unbound(&self, var: Rc<Var>) -> bool {
self.get(var) == temp_v!(0) self.get(var).reg_num() == 0
} }
fn record_register(&mut self, var: Rc<Var>, r: RegType) { fn record_register(&mut self, var: Rc<Var>, r: RegType) {

View File

@@ -668,7 +668,8 @@ pub type JumpStub = Vec<Term>;
pub enum QueryTerm { pub enum QueryTerm {
Clause(Cell<RegType>, ClauseType, Vec<Box<Term>>), Clause(Cell<RegType>, ClauseType, Vec<Box<Term>>),
Cut, BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
UnblockedCut,
Jump(JumpStub) Jump(JumpStub)
} }
@@ -676,7 +677,7 @@ impl QueryTerm {
pub fn arity(&self) -> usize { pub fn arity(&self) -> usize {
match self { match self {
&QueryTerm::Clause(_, _, ref subterms) => subterms.len(), &QueryTerm::Clause(_, _, ref subterms) => subterms.len(),
&QueryTerm::Cut => 0, &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut => 0,
&QueryTerm::Jump(ref vars) => vars.len() &QueryTerm::Jump(ref vars) => vars.len()
} }
} }

View File

@@ -161,6 +161,17 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
} else { } else {
self.marker.mark_anon_var(lvl, &mut target); self.marker.mark_anon_var(lvl, &mut target);
}, },
TermRef::Var(lvl @ Level::Shallow, cell, ref var) if var.as_str() == "!" => {
if self.marker.is_unbound(var.clone()) {
if term_loc != GenContext::Head {
self.marker.mark_reserved_var(var.clone(), lvl, cell, term_loc,
&mut target, perm_v!(1), false);
continue;
}
}
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target);
},
TermRef::Var(lvl @ Level::Shallow, cell, var) => TermRef::Var(lvl @ Level::Shallow, cell, var) =>
self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target), self.marker.mark_var(var.clone(), lvl, cell, term_loc, &mut target),
_ => {} _ => {}
@@ -397,7 +408,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
}; };
match *term { match *term {
&QueryTerm::Cut => &QueryTerm::UnblockedCut =>
code.push(set_cp!(self.marker.get(rc_atom!("!")))),
&QueryTerm::BlockedCut =>
code.push(if chunk_num == 0 { code.push(if chunk_num == 0 {
Line::Cut(CutInstruction::NeckCut) Line::Cut(CutInstruction::NeckCut)
} else { } else {
@@ -469,7 +482,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
{ {
// add a proceed to bookend any trailing cuts. // add a proceed to bookend any trailing cuts.
match toc { match toc {
&QueryTerm::Cut => code.push(proceed!()), &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut => code.push(proceed!()),
_ => {} _ => {}
}; };

View File

@@ -249,7 +249,7 @@ impl<'a> Allocator<'a> for DebrayAllocator
} }
} }
fn mark_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &Cell<VarReg>, fn mark_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &'a Cell<VarReg>,
term_loc: GenContext, target: &mut Vec<Target>) term_loc: GenContext, target: &mut Vec<Target>)
where Target: CompilationTarget<'a> where Target: CompilationTarget<'a>
{ {
@@ -271,6 +271,14 @@ impl<'a> Allocator<'a> for DebrayAllocator
r => (r, false) r => (r, false)
}; };
self.mark_reserved_var(var, lvl, cell, term_loc, target, r, is_new_var);
}
fn mark_reserved_var<Target>(&mut self, var: Rc<Var>, lvl: Level, cell: &'a Cell<VarReg>,
term_loc: GenContext, target: &mut Vec<Target>, r: RegType,
is_new_var: bool)
where Target: CompilationTarget<'a>
{
match lvl { match lvl {
Level::Root | Level::Shallow => { Level::Root | Level::Shallow => {
let k = self.arg_c; let k = self.arg_c;

View File

@@ -540,6 +540,8 @@ fn compile_query(terms: Vec<QueryTerm>, queue: Vec<TopLevel>, code_size: usize,
let query_info = QueryInfo {}; let query_info = QueryInfo {};
query_info.label_clauses(code_size, code_dir, &mut code); query_info.label_clauses(code_size, code_dir, &mut code);
print_code(&code);
Ok((code, cg.take_vars())) Ok((code, cg.take_vars()))
} }
@@ -571,6 +573,8 @@ fn compile_decl(wam: &mut Machine, tl: TopLevel, queue: Vec<TopLevel>) -> EvalSe
decl_info.label_clauses(wam.code_size(), &mut wam.code_dir, &mut code); decl_info.label_clauses(wam.code_size(), &mut wam.code_dir, &mut code);
print_code(&code);
if !code.is_empty() { if !code.is_empty() {
wam.add_user_code(name, tl.arity(), code, tl.as_predicate().unwrap()) wam.add_user_code(name, tl.arity(), code, tl.as_predicate().unwrap())
} else { } else {

View File

@@ -50,7 +50,8 @@ impl<'a> QueryIterator<'a> {
let state = TermIterState::Clause(Level::Root, 0, cell, ct.clone(), terms); let state = TermIterState::Clause(Level::Root, 0, cell, ct.clone(), terms);
QueryIterator { state_stack: vec![state] } QueryIterator { state_stack: vec![state] }
}, },
&QueryTerm::Cut => QueryIterator { state_stack: vec![] }, &QueryTerm::BlockedCut | &QueryTerm::UnblockedCut =>
QueryIterator { state_stack: vec![] },
&QueryTerm::Jump(ref vars) => { &QueryTerm::Jump(ref vars) => {
let state_stack = vars.iter().rev().map(|t| { let state_stack = vars.iter().rev().map(|t| {
TermIterState::subterm_to_state(Level::Shallow, t) TermIterState::subterm_to_state(Level::Shallow, t)
@@ -213,11 +214,24 @@ impl<'a> ChunkedTerm<'a> {
} }
} }
fn contains_cut_var<'a, Iter: Iterator<Item=&'a Term>>(terms: Iter) -> bool {
for term in terms {
if let &Term::Var(_, ref var) = term {
if var.as_str() == "!" {
return true;
}
}
}
false
}
pub struct ChunkedIterator<'a> pub struct ChunkedIterator<'a>
{ {
pub chunk_num: usize, pub chunk_num: usize,
iter: Box<Iterator<Item=ChunkedTerm<'a>> + 'a>, iter: Box<Iterator<Item=ChunkedTerm<'a>> + 'a>,
deep_cut_encountered: bool deep_cut_encountered: bool,
cut_var_in_head: bool
} }
type ChunkedIteratorItem<'a> = (usize, usize, Vec<ChunkedTerm<'a>>); type ChunkedIteratorItem<'a> = (usize, usize, Vec<ChunkedTerm<'a>>);
@@ -248,7 +262,8 @@ impl<'a> ChunkedIterator<'a>
ChunkedIterator { ChunkedIterator {
chunk_num: 0, chunk_num: 0,
iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))), iter: Box::new(terms.iter().map(|t| ChunkedTerm::BodyTerm(t))),
deep_cut_encountered: false deep_cut_encountered: false,
cut_var_in_head: false
} }
} }
@@ -260,7 +275,8 @@ impl<'a> ChunkedIterator<'a>
ChunkedIterator { ChunkedIterator {
chunk_num: 0, chunk_num: 0,
iter: Box::new(iter), iter: Box::new(iter),
deep_cut_encountered: false deep_cut_encountered: false,
cut_var_in_head: false
} }
} }
@@ -276,6 +292,7 @@ impl<'a> ChunkedIterator<'a>
chunk_num: 0, chunk_num: 0,
iter: Box::new(iter), iter: Box::new(iter),
deep_cut_encountered: false, deep_cut_encountered: false,
cut_var_in_head: false
} }
} }
@@ -291,20 +308,32 @@ impl<'a> ChunkedIterator<'a>
while let Some(term) = item { while let Some(term) = item {
match term { match term {
ChunkedTerm::HeadClause(..) => ChunkedTerm::HeadClause(_, terms) => {
result.push(term), if contains_cut_var(terms.iter().map(|t| t.as_ref())) {
self.cut_var_in_head = true;
}
result.push(term);
},
ChunkedTerm::BodyTerm(&QueryTerm::Jump(ref vars)) => { ChunkedTerm::BodyTerm(&QueryTerm::Jump(ref vars)) => {
result.push(term); result.push(term);
arity = vars.len(); arity = vars.len();
if contains_cut_var(vars.iter()) && !self.cut_var_in_head {
self.deep_cut_encountered = true;
}
break; break;
}, },
ChunkedTerm::BodyTerm(&QueryTerm::Cut) => { ChunkedTerm::BodyTerm(&QueryTerm::BlockedCut) => {
result.push(term); result.push(term);
if self.chunk_num > 0 { if self.chunk_num > 0 {
self.deep_cut_encountered = true; self.deep_cut_encountered = true;
} }
}, },
ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut) =>
result.push(term),
ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), _)) => ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), _)) =>
result.push(term), result.push(term),
ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) => { ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::CallN, ref subterms)) => {

View File

@@ -306,9 +306,8 @@ impl Machine {
{ {
for (var, var_data) in alloc_locs { for (var, var_data) in alloc_locs {
match var_data { match var_data {
&VarData::Perm(_) => { &VarData::Perm(p) if p > 0 => {
let e = self.ms.e; let e = self.ms.e;
let r = var_data.as_reg_type().reg_num(); let r = var_data.as_reg_type().reg_num();
let addr = self.ms.and_stack[e][r].clone(); let addr = self.ms.and_stack[e][r].clone();