1use std::collections::HashMap;
2
3#[derive(Clone, PartialEq)]
4enum Cell {
5 Variable(Address), Structure(Address), Functor(String, usize), }
9
10impl std::fmt::Debug for Cell {
11 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
12 match self {
13 &Cell::Variable(bind) => write!(f, "REF {:?}", bind),
14 &Cell::Structure(ptr) => write!(f, "STR {:?}", ptr),
15 &Cell::Functor(ref name, arity) => write!(f, "{}/{}", name, arity),
16 }
17 }
18}
19
20#[derive(Clone, Debug)]
21pub enum Instruction {
22 PutStructure(String, usize, Address), SetVariable(Address), SetValue(Address), GetStructure(String, usize, Address), UnifyVariable(Address), UnifyValue(Address), PutVariable(Address, Address), PutValue(Address, Address), GetVariable(Address, Address), GetValue(Address, Address), Call(String), Proceed,
41}
42
43enum Mode {
44 Read,
45 Write,
46}
47
48#[derive(Clone, PartialEq, Debug, Copy)]
49pub enum Address {
50 Heap(usize),
51 Register(usize),
52}
53
54impl std::ops::Add<usize> for Address {
55 type Output = Address;
56
57 fn add(self, rhs: usize) -> Address {
58 match self {
59 Address::Heap(a) => Address::Heap(a + rhs),
60 Address::Register(a) => Address::Register(a + rhs),
61 }
62 }
63}
64
65pub struct Instance {
66 heap: Vec<Cell>,
67 registers: Vec<Option<Cell>>,
68 mode: Mode,
69 s_ptr: Address,
70 instructions: Vec<Instruction>,
71 pc: usize,
72 labels: HashMap<String, usize>,
73}
74
75const REGISTER_COUNT: usize = 100;
76
77impl Instance {
78
79 pub fn new() -> Instance {
80 Instance {
81 heap: Vec::new(),
82 registers: vec![None; REGISTER_COUNT],
83 mode: Mode::Read,
84 s_ptr: Address::Heap(0),
85 instructions: Vec::new(),
86 pc: 0,
87 labels: HashMap::new(),
88 }
89 }
90
91 fn set_cell(&mut self, address: Address, cell: Cell) {
92 match address {
93 Address::Heap(a) => self.heap[a] = cell,
94 Address::Register(a) => self.registers[a] = Some(cell),
95 }
96 }
97
98 fn fetch_cell(&self, address: Address) -> Cell {
99 match address {
100 Address::Heap(a) => self.heap[a].clone(),
101 Address::Register(a) => self.registers[a].clone().unwrap(),
102 }
103 }
104
105 fn deref(&self, address: Address) -> Address {
106 match self.fetch_cell(address) {
107 Cell::Variable(v_address) => {
108 if address == v_address {
109 address
110 } else {
111 self.deref(v_address)
112 }
113 },
114 _ => address,
115 }
116 }
117
118 fn bind(&mut self, a1: Address, a2: Address) {
119 let cells = (self.fetch_cell(a1), self.fetch_cell(a2));
120 let (var_address, target_adresss) = match cells {
121 (Cell::Variable(_), _) => (a1, a2),
122 (_, Cell::Variable(_)) => (a2, a1),
123 _ => panic!("neiter {:?} or {:?} points to a variable", a1, a2)
124 };
125
126 self.set_cell(var_address, Cell::Variable(target_adresss));
128 }
129
130 pub fn load(&mut self, instructions: Vec<Instruction>) {
131 self.instructions.extend(instructions);
132 }
133
134 pub fn load_labeled(&mut self, label: String, instructions: Vec<Instruction>) {
135 let index = self.instructions.len();
136 self.load(instructions);
137 self.labels.insert(label, index - 1);
138 }
139
140 fn inst_put_structure(&mut self, name: String, arity: usize, register: Address) {
141 let str_index = self.heap.len();
142 let str_cell = Cell::Structure(Address::Heap(str_index + 1));
143 self.heap.push(str_cell.clone());
144 self.heap.push(Cell::Functor(name.clone(), arity.clone()));
145 self.set_cell(register, str_cell);
146 }
147
148 fn inst_set_variable(&mut self, register: Address) {
149 let ref_index = self.heap.len();
150 let ref_cell = Cell::Variable(Address::Heap(ref_index));
151 self.heap.push(ref_cell.clone());
152 self.set_cell(register, ref_cell);
153 }
154
155 fn inst_set_value(&mut self, register: Address) {
156 let cell = self.fetch_cell(register);
157 self.heap.push(cell);
158 }
159
160 fn inst_get_structure(&mut self, name: String, arity: usize, register: Address) {
161 let address = self.deref(register);
162 match self.fetch_cell(address) {
163 Cell::Variable(_) => {
164 let str_index = self.heap.len();
165 self.heap.push(Cell::Structure(Address::Heap(str_index + 1)));
166 self.heap.push(Cell::Functor(name, arity));
167 self.bind(address, Address::Heap(str_index));
168 self.mode = Mode::Write;
169 },
170 Cell::Structure(a) => {
171 let cell = self.fetch_cell(a);
172 if cell == Cell::Functor(name, arity) {
173 self.s_ptr = a + 1;
174 self.mode = Mode::Read;
175 } else {
176 panic!("fail");
177 }
178 },
179 _ => panic!("fail"),
180 }
181 }
182
183 fn inst_unify_variable(&mut self, register: Address) {
184 match self.mode {
185 Mode::Read => {
186 let cell = self.fetch_cell(self.s_ptr);
187 self.set_cell(register, cell);
188 },
189 Mode::Write => {
190 let ref_index = self.heap.len();
191 let cell = Cell::Variable(Address::Heap(ref_index));
192 self.heap.push(cell.clone());
193 self.set_cell(register, cell);
194 }
195 }
196
197 self.s_ptr = self.s_ptr + 1;
198 }
199
200 fn inst_unift_value(&mut self, register: Address) {
201 match self.mode {
202 Mode::Read => {
203 let s = self.s_ptr;
204 self.unify(register, s);
205 },
206 Mode::Write => {
207 let cell = self.fetch_cell(register);
208 self.heap.push(cell);
209 }
210 }
211 }
212
213 fn inst_put_variable(&mut self, register_n: Address, register_i: Address) {
214 let ref_index = self.heap.len();
215 let cell = Cell::Variable(Address::Heap(ref_index));
216 self.heap.push(cell.clone());
217 self.set_cell(register_n, cell.clone());
218 self.set_cell(register_i, cell);
219 }
220
221 fn inst_put_value(&mut self, register_n: Address, register_i: Address) {
222 let cell = self.fetch_cell(register_n);
223 self.set_cell(register_i, cell);
224 }
225
226 fn inst_get_variable(&mut self, register_n: Address, register_i: Address) {
227 let cell = self.fetch_cell(register_i);
228 self.set_cell(register_n, cell);
229 }
230
231 fn inst_get_value(&mut self, register_n: Address, register_i: Address) {
232 self.unify(register_n, register_i);
233 }
234
235 fn inst_call(&mut self, label: String) {
236 if self.labels.contains_key(&label) {
237 self.pc = *self.labels.get(&label).unwrap();
238 } else {
239 panic!("Unification error");
240 }
241 }
242
243 fn fetch_instruction(&self) -> Option<Instruction> {
244 if self.instructions.len() <= self.pc {
245 None
246 } else {
247 Some(self.instructions[self.pc].clone())
248 }
249 }
250
251 pub fn execute(&mut self) {
252 println!("Executing {:?}", self.fetch_instruction());
253
254 match self.fetch_instruction() {
255 Some(instruction) => match instruction {
256 Instruction::PutStructure(name, arity, register) => self.inst_put_structure(name, arity, register),
257 Instruction::SetVariable(register) => self.inst_set_variable(register),
258 Instruction::SetValue(register) => self.inst_set_value(register),
259 Instruction::GetStructure(name, arity, register) => self.inst_get_structure(name, arity, register),
260 Instruction::UnifyVariable(register) => self.inst_unify_variable(register),
261 Instruction::UnifyValue(register) => self.inst_unift_value(register),
262 Instruction::PutVariable(register_n, register_i) => self.inst_put_variable(register_n, register_i),
263 Instruction::PutValue(register_n, register_i) => self.inst_put_value(register_n, register_i),
264 Instruction::GetVariable(register_n, register_i) => self.inst_get_variable(register_n, register_i),
265 Instruction::GetValue(register_n, register_i) => self.inst_get_value(register_n, register_i),
266 Instruction::Call(label) => self.inst_call(label),
267 Instruction::Proceed => return,
268 }
269 None => return
270 }
271
272 self.pc += 1;
273 self.execute();
274 }
275
276 fn unify(&mut self, ad1: Address, ad2: Address) {
277 let mut pdl = Vec::new();
278 pdl.push(ad1);
279 pdl.push(ad2);
280
281 while !pdl.is_empty() {
282 let d1 = self.deref(pdl.pop().unwrap());
283 let d2 = self.deref(pdl.pop().unwrap());
284 println!("{:?} <> {:?}", d1, d2);
285 if d1 != d2 {
286 match (self.fetch_cell(d1), self.fetch_cell(d2)) {
287 (Cell::Variable(_), _) => self.bind(d1, d2),
288 (_, Cell::Variable(_)) => self.bind(d1, d2),
289 (Cell::Structure(str_1), Cell::Structure(str_2)) => {
290 match (self.fetch_cell(str_1), self.fetch_cell(str_2)) {
291 (Cell::Functor(f1, n1), Cell::Functor(f2, n2)) => {
292 if f1 != f2 || n1 != n2 {
293 panic!("functors {}/{} and {}/{} do not match", f1, n1, f2, n2);
294 }
295 for i in 1..(n1+1) {
296 pdl.push(str_1 + i);
297 pdl.push(str_2 + i);
298 }
299 },
300 _ => panic!("structure cell addresses unwrapped to {:?} and {:?}", self.fetch_cell(str_1), self.fetch_cell(str_2)),
301 }
302 }
303 _ => {
304 panic!("cannot unify {:?} and {:?}", self.fetch_cell(d1), self.fetch_cell(d2));
305 },
306 }
307 }
308 }
309 }
310
311 pub fn dump_heap(&self) {
312 println!("HEAP:");
313 for (index, cell) in self.heap.iter().enumerate() {
314 println!("{:4} | {:?}", index, cell);
315 }
316 }
317
318 pub fn dump_registers(&self) {
319 println!("REGISTERS:");
320 for (index, content) in self.registers.iter().enumerate() {
321 println!("X_{} = {:?}", index, content);
322 }
323 }
324
325}
326
327#[cfg(test)]
328mod tests {
329 use super::*;
330
331 fn instruction_set_1() -> Vec<Instruction> {
332 vec![
333 Instruction::PutStructure(String::from("h"), 2, Address::Register(3)),
334 Instruction::SetVariable(Address::Register(2)),
335 Instruction::SetVariable(Address::Register(5)),
336 Instruction::PutStructure(String::from("f"), 1, Address::Register(4)),
337 Instruction::SetValue(Address::Register(5)),
338 Instruction::PutStructure(String::from("p"), 3, Address::Register(1)),
339 Instruction::SetValue(Address::Register(2)),
340 Instruction::SetValue(Address::Register(3)),
341 Instruction::SetValue(Address::Register(4)),
342 ]
343 }
344
345 fn instruction_set_2() -> Vec<Instruction> {
346 vec![
347 Instruction::GetStructure(String::from("p"), 3, Address::Register(1)),
348 Instruction::UnifyVariable(Address::Register(2)),
349 Instruction::UnifyVariable(Address::Register(3)),
350 Instruction::UnifyVariable(Address::Register(4)),
351 Instruction::GetStructure(String::from("f"), 1, Address::Register(2)),
352 Instruction::UnifyVariable(Address::Register(5)),
353 Instruction::GetStructure(String::from("h"), 2, Address::Register(3)),
354 Instruction::UnifyValue(Address::Register(4)),
355 Instruction::UnifyVariable(Address::Register(6)),
356 Instruction::GetStructure(String::from("f"), 1, Address::Register(6)),
357 Instruction::UnifyVariable(Address::Register(7)),
358 Instruction::GetStructure(String::from("a"), 0, Address::Register(7)),
359 ]
360 }
361
362 fn instruction_set_3() -> Vec<Instruction> {
363 vec![
364 Instruction::PutVariable(Address::Register(4), Address::Register(1)),
365 Instruction::PutStructure(String::from("h"), 2, Address::Register(2)),
366 Instruction::SetValue(Address::Register(4)),
367 Instruction::SetVariable(Address::Register(5)),
368 Instruction::PutStructure(String::from("f"), 1, Address::Register(3)),
369 Instruction::SetValue(Address::Register(5)),
370 Instruction::Call(String::from("p/3")),
371 ]
372 }
373
374 fn instruction_set_4() -> (String, Vec<Instruction>) {
375 (String::from("p/3"), vec![
376 Instruction::GetStructure(String::from("f"), 1, Address::Register(1)),
377 Instruction::Proceed,
378 Instruction::UnifyVariable(Address::Register(1)),
379 Instruction::GetStructure(String::from("h"), 2, Address::Register(2)),
380 Instruction::UnifyVariable(Address::Register(5)),
381 Instruction::UnifyVariable(Address::Register(6)),
382 Instruction::GetValue(Address::Register(5), Address::Register(3)),
383 Instruction::GetStructure(String::from("f"), 1, Address::Register(6)),
384 Instruction::UnifyVariable(Address::Register(7)),
385 Instruction::GetStructure(String::from("a"), 0, Address::Register(7)),
386 ])
387 }
388
389 #[test]
390 fn query_term_instructions() {
391 let mut inst = Instance::new();
392 inst.load(instruction_set_1());
393 inst.execute();
394
395 let expected_heap = vec![
396 Cell::Structure(Address::Heap(1)),
397 Cell::Functor(String::from("h"), 2),
398 Cell::Variable(Address::Heap(2)),
399 Cell::Variable(Address::Heap(3)),
400 Cell::Structure(Address::Heap(5)),
401 Cell::Functor(String::from("f"), 1),
402 Cell::Variable(Address::Heap(3)),
403 Cell::Structure(Address::Heap(8)),
404 Cell::Functor(String::from("p"), 3),
405 Cell::Variable(Address::Heap(2)),
406 Cell::Structure(Address::Heap(1)),
407 Cell::Structure(Address::Heap(5)),
408 ];
409
410 assert_eq!(inst.heap, expected_heap);
411 }
412
413 #[test]
414 fn unify() {
415 let instructions = vec![
416 Instruction::PutStructure(String::from("a"), 0, Address::Register(4)),
422 Instruction::PutStructure(String::from("g"), 2, Address::Register(3)),
423 Instruction::SetVariable(Address::Register(2)),
424 Instruction::SetValue(Address::Register(4)),
425 Instruction::PutStructure(String::from("f"), 2, Address::Register(1)),
426 Instruction::SetValue(Address::Register(2)),
427 Instruction::SetValue(Address::Register(3)),
428
429 Instruction::PutStructure(String::from("b"), 0, Address::Register(6)),
434 Instruction::PutStructure(String::from("f"), 2, Address::Register(5)),
435 Instruction::SetValue(Address::Register(6)),
436 Instruction::SetVariable(Address::Register(7)),
437 ];
438
439 let mut inst = Instance::new();
440 inst.load(instructions);
441 inst.execute();
442
443 let expected_heap = vec![
444 Cell::Structure(Address::Heap(1)),
445 Cell::Functor(String::from("a"), 0),
446 Cell::Structure(Address::Heap(3)),
447 Cell::Functor(String::from("g"), 2),
448 Cell::Variable(Address::Heap(4)),
449 Cell::Structure(Address::Heap(1)),
450 Cell::Structure(Address::Heap(7)),
451 Cell::Functor(String::from("f"), 2),
452 Cell::Variable(Address::Heap(4)),
453 Cell::Structure(Address::Heap(3)),
454 Cell::Structure(Address::Heap(11)),
455 Cell::Functor(String::from("b"), 0),
456 Cell::Structure(Address::Heap(13)),
457 Cell::Functor(String::from("f"), 2),
458 Cell::Structure(Address::Heap(11)),
459 Cell::Variable(Address::Heap(15)),
460 ];
461
462 assert_eq!(inst.heap, expected_heap);
463
464 inst.unify(Address::Heap(6), Address::Heap(12));
465
466 let expected_heap = vec![
467 Cell::Structure(Address::Heap(1)),
468 Cell::Functor(String::from("a"), 0),
469 Cell::Structure(Address::Heap(3)),
470 Cell::Functor(String::from("g"), 2),
471 Cell::Variable(Address::Heap(14)), Cell::Structure(Address::Heap(1)),
473 Cell::Structure(Address::Heap(7)),
474 Cell::Functor(String::from("f"), 2),
475 Cell::Variable(Address::Heap(4)),
476 Cell::Structure(Address::Heap(3)),
477 Cell::Structure(Address::Heap(11)),
478 Cell::Functor(String::from("b"), 0),
479 Cell::Structure(Address::Heap(13)),
480 Cell::Functor(String::from("f"), 2),
481 Cell::Structure(Address::Heap(11)),
482 Cell::Variable(Address::Heap(9)), ];
484
485 assert_eq!(inst.heap, expected_heap);
486
487 }
488
489 #[test]
490 fn program_instructions() {
491 let mut inst = Instance::new();
492 inst.load(instruction_set_1());
493 inst.load(instruction_set_2());
494 inst.execute();
495
496 let expected_heap = vec![
497 Cell::Structure(Address::Heap(1)),
498 Cell::Functor(String::from("h"), 2),
499 Cell::Variable(Address::Heap(12)),
500 Cell::Variable(Address::Heap(14)),
501 Cell::Structure(Address::Heap(5)),
502 Cell::Functor(String::from("f"), 1),
503 Cell::Variable(Address::Heap(3)),
504 Cell::Structure(Address::Heap(8)),
505 Cell::Functor(String::from("p"), 3),
506 Cell::Variable(Address::Heap(2)),
507 Cell::Structure(Address::Heap(1)),
508 Cell::Structure(Address::Heap(5)),
509 Cell::Structure(Address::Heap(13)),
510 Cell::Functor(String::from("f"), 1),
511 Cell::Variable(Address::Heap(15)),
512 Cell::Structure(Address::Heap(16)),
513 Cell::Functor(String::from("a"), 0),
514 ];
515
516 assert_eq!(inst.heap, expected_heap);
517
518 }
519
520 #[test]
521 fn argument_instructions_1() {
522 let mut inst_1 = Instance::new();
523 inst_1.load(instruction_set_1());
524 inst_1.execute();
525
526 let mut inst_2 = Instance::new();
527 inst_2.load(instruction_set_3());
528 let (label, instructions) = instruction_set_4();
529 inst_2.load_labeled(label, instructions);
530 inst_2.execute();
531
532 assert_eq!(inst_1.heap, inst_2.heap);
533 }
534}