let mut code = Vec::new();
self.marker.reset_arg(args.len());
+ self.marker.reset_at_head(args);
self.compile_seq_prelude(&conjunct_info, &mut code);
let iter = FactIterator::from_rule_head_clause(args);
vs.mark_vars_in_chunk(term.post_order_iter(), term.arity(), GenContext::Head);
vs.populate_restricting_sets();
-
self.marker.drain_var_data(vs);
- self.marker.reset_arg(term.arity());
-
+
let mut code = Vec::new();
- if let &Term::Clause(..) = term {
+ if let &Term::Clause(_, _, ref args, _) = term {
+ self.marker.reset_arg(args.len());
+ self.marker.reset_at_head(args);
+
let iter = FactInstruction::iter(term);
let mut compiled_fact = self.compile_target(iter, GenContext::Head, false);
if r != k {
let r = RegType::Temp(r);
- if r.reg_num() != k {
- target.push(Target::move_to_register(r, k));
-
- self.contents.remove(&k);
- self.contents.insert(r.reg_num(), var.clone());
-
- self.record_register(var, r);
- self.in_use.insert(r.reg_num());
- }
+ target.push(Target::move_to_register(r, k));
+
+ self.contents.remove(&k);
+ self.contents.insert(r.reg_num(), var.clone());
+
+ self.record_register(var, r);
+ self.in_use.insert(r.reg_num());
}
},
_ => {}
}
};
}
-
+
fn mark_non_var<Target>(&mut self, lvl: Level, term_loc: GenContext,
cell: &Cell<RegType>, target: &mut Vec<Target>)
where Target: CompilationTarget<'a>
self.bindings
}
+ fn reset_at_head(&mut self, args: &Vec<Box<Term>>) {
+ for (idx, arg) in args.iter().enumerate() {
+ if let &Term::Var(_, ref var) = arg.as_ref() {
+ self.contents.insert(idx + 1, var.clone());
+ self.in_use.insert(idx + 1);
+ }
+ }
+ }
+
fn reset_arg(&mut self, arity: usize) {
self.arg_c = 1;
- self.temp_lb = arity + 1;
+ self.temp_lb = arity + 1;
}
}
--- /dev/null
+:- module(queues, [queue/1, queue/2, queue_head/3, queue_head_list/3,
+ queue_last/3, queue_last_list/3, list_queue/2,
+ queue_length/2]).
+
+/* true when Queue is a queue with no elements. */
+queue(q(0,B,B)).
+
+/* true when Queue is a queue with one element. */
+queue(X, q(s(0), [X|B], B)).
+
+/* true when Queue0 and Queue1 have the same elements except that
+ * Queue0 has in addition X at the front. Use it for enqueuing and
+ * dequeuing both.
+*/
+queue_head(X, q(N, F, B), q(s(N), [X|F], B)).
+
+/* true when append(List, Queue1, Queue0) would be true if only Queue1
+ * and Queue0 were lists instead of queues.
+*/
+queue_head_list([], Queue, Queue).
+queue_head_list([X|Xs], Queue, Queue0) :-
+ queue_head(X, Queue1, Queue0),
+ queue_head_list(Xs, Queue, Queue1).
+
+/* true when Queue0 and Queue1 have the same elements except that
+ * Queue0 has in addition to X at the end.
+*/
+queue_last(X, q(N, F, [X|B]), q(s(N), F, B)).
+
+/* true when append(Queue1, List, Queue0) would be true if only Queue1
+ * and Queue0 were lists instead of queues.
+*/
+queue_last_list([], Queue, Queue).
+queue_last_list([X|Xs], Queue1, Queue) :-
+ queue_last(X, Queue1, Queue2),
+ queue_last_list(Xs, Queue2, Queue).
+
+/* true when List is a list and Queue is a queue and they represent
+ * the same sequence.
+*/
+list_queue(List, q(Count, Front, Back)) :-
+ list_queue(List, Count, Front, Back).
+
+list_queue([], 0, B, B).
+list_queue([X|Xs], s(N), [X|F], B) :-
+ list_queue(Xs, N, F, B).
+
+/* is true when Length is (a binary length representing) the number of
+ * elements in (the queue represented by) Queue. This version cannot
+ * be used to generate a Queue, only to determine the Length.
+*/
+queue_length(q(Count, F, B), Length) :-
+ queue_length(Count, F, B, 0, Length).
+
+queue_length(0, B, B, Length, Length).
+queue_length(s(N), [_|Front], Back, L0, Length) :-
+ L1 is L0 + 1,
+ queue_length(N, Front, Back, L1, Length).