}
enum IntTerm<'a> {
- FinishedClause(usize, &'a Atom, &'a Vec<Box<Term>>),
+ FinishedClause(usize, usize, &'a Atom, &'a Vec<Box<Term>>),
UnfinishedClause(usize, &'a Atom, &'a Vec<Box<Term>>),
FinishedAtom(usize, &'a Atom)
}
match t {
&Term::Clause(ref atom, ref terms) => {
stack.push(IntTerm::UnfinishedClause(1, atom, terms));
- variable_allocs.insert(atom, (1, true));
+ variable_allocs.insert(atom, (1, true));
},
&Term::Atom(ref atom) => {
query.push(MachineInstruction::PutStructure(atom.clone(), 0, 1));
},
};
+ let mut max_reg_used : usize = 1;
+
while let Some(int_term) = stack.pop() {
match int_term {
IntTerm::UnfinishedClause(r, atom, terms) => {
- stack.push(IntTerm::FinishedClause(r, atom, terms));
+ stack.push(IntTerm::FinishedClause(r, max_reg_used, atom, terms));
- let mut counter : usize = r + 1;
-
- for t in terms {
+ let mut counter : usize = max_reg_used; // r + 1;
+
+ for t in terms {
if t.is_variable() && !variable_allocs.contains_key(t.name()) {
- variable_allocs.insert(t.name(), (counter, false));
+ counter += 1;
+ variable_allocs.insert(t.name(), (counter, false));
+ } else if !t.is_variable() {
+ counter += 1;
}
-
- counter += 1;
}
- counter = r + terms.len();
-
+ max_reg_used = counter;
+
for t in terms.iter().rev() {
let r = if t.is_variable() {
variable_allocs.get(t.name()).unwrap().0
} else {
- counter
- };
-
+ let oc = counter;
+ counter -= 1;
+ oc
+ };
+
match t.as_ref() {
- &Term::Atom(ref atom) =>
+ &Term::Atom(ref atom) =>
stack.push(IntTerm::FinishedAtom(r, atom)),
- &Term::Clause(ref atom, ref terms) =>
+ &Term::Clause(ref atom, ref terms) =>
stack.push(IntTerm::UnfinishedClause(r, atom, terms)),
_ => {}
- };
-
- counter -= 1;
+ };
}
},
IntTerm::FinishedAtom(r, atom) =>
- query.push(MachineInstruction::PutStructure(atom.clone(), 0, r)),
- IntTerm::FinishedClause(r, atom, terms) => {
+ query.push(MachineInstruction::PutStructure(atom.clone(), 0, r)),
+ IntTerm::FinishedClause(r, mr, atom, terms) => {
query.push(MachineInstruction::PutStructure(atom.clone(), terms.len(), r));
- let mut counter : usize = r + 1;
-
+ let mut counter : usize = mr + 1;
+
for t in terms {
if let &Term::Var(ref var) = t.as_ref() {
let &mut (reg, ref mut seen) = variable_allocs.get_mut(var).unwrap();
} else {
query.push(MachineInstruction::SetValue(reg));
}
+
+ if reg == counter {
+ counter += 1;
+ }
} else {
query.push(MachineInstruction::SetValue(counter));
- }
-
- counter += 1;
+ counter += 1;
+ }
}
+
+ max_reg_used = counter - 1;
}
};
}
let mut variable_allocs : HashMap<&Var, usize> = HashMap::new();
let mut fact : Program = Vec::new();
- queue.push_back((1, t));
+ queue.push_back((1, t));
- while let Some(t) = queue.pop_front() {
+ while let Some(t) = queue.pop_front() {
match t {
(r, &Term::Clause(ref atom, ref terms)) => {
fact.push(MachineInstruction::GetStructure(atom.clone(), terms.len(), r));
-
+
let mut counter : usize = reg;
-
+
for t in terms {
if t.is_variable() && !variable_allocs.contains_key(t.name()) {
variable_allocs.insert(t.name(), counter);
fact.push(MachineInstruction::UnifyVariable(counter));
queue.push_back((counter, t));
counter += 1;
- }
+ }
}
reg = counter;
self.h += 1;
},
MachineInstruction::UnifyVariable(reg) => {
- if self.s < self.h {
- match self.mode {
- MachineMode::Read => self.registers[reg] = self.heap[self.s].clone(),
- MachineMode::Write => {
- self.heap.push(HeapCell::Ref(self.h));
- self.registers[reg] = self.heap[self.h].clone();
- self.h += 1;
- }
- };
-
- self.s += 1;
- } else {
- self.fail = true;
- }
+ match self.mode {
+ MachineMode::Read => self.registers[reg] = self.heap[self.s].clone(),
+ MachineMode::Write => {
+ self.heap.push(HeapCell::Ref(self.h));
+ self.registers[reg] = self.heap[self.h].clone();
+ self.h += 1;
+ }
+ };
},
MachineInstruction::UnifyValue(reg) => {
- if self.s < self.h {
- let s = self.s;
-
- match self.mode {
- MachineMode::Read => self.unify(Addr::RegNum(reg), Addr::HeapCell(s)),
- MachineMode::Write => {
- self.heap.push(self.registers[reg].clone());
- self.h += 1;
- }
- };
-
- self.s += 1;
- } else {
- self.fail = true;
- }
+ let s = self.s;
+
+ match self.mode {
+ MachineMode::Read => self.unify(Addr::RegNum(reg), Addr::HeapCell(s)),
+ MachineMode::Write => {
+ self.heap.push(self.registers[reg].clone());
+ self.h += 1;
+ }
+ };
+
+ self.s += 1;
}
}
}