add top level declarative structure
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1,6 +1,6 @@
|
||||
[root]
|
||||
name = "rusty-wam"
|
||||
version = "0.6.2"
|
||||
version = "0.6.3"
|
||||
dependencies = [
|
||||
"lalrpop 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lalrpop-util 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rusty-wam"
|
||||
version = "0.6.2"
|
||||
version = "0.6.3"
|
||||
authors = ["Mark Thom"]
|
||||
|
||||
build = "build.rs"
|
||||
|
||||
44
README.md
44
README.md
@@ -46,11 +46,10 @@ prolog> ?- p(X, Y, Z).
|
||||
Given the above work, the result of the query will be
|
||||
```
|
||||
prolog> ?- p(X, Y, Z).
|
||||
yes
|
||||
X = _0
|
||||
true
|
||||
Y = x
|
||||
X = _0
|
||||
Z = _2
|
||||
Press ; to continue or . to abort.
|
||||
```
|
||||
|
||||
Pressing ; will backtrack through other possible answers, if any exist.
|
||||
@@ -63,40 +62,29 @@ prolog> :{
|
||||
member(X, [X|_]).
|
||||
member(X, [_|Xs]) :- member(X, Xs).
|
||||
}:
|
||||
prolog> ?- member(X, [a, b, c]).
|
||||
yes
|
||||
X = a
|
||||
Press ; to continue or . to abort.
|
||||
;
|
||||
X = b
|
||||
Press ; to continue or . to abort.
|
||||
;
|
||||
X = c
|
||||
Press ; to continue or . to abort.
|
||||
;
|
||||
no
|
||||
prolog> ?- member(X, [a, b, c]).
|
||||
true
|
||||
X = a ;
|
||||
X = b ;
|
||||
X = c ;
|
||||
false.
|
||||
```
|
||||
and so do conjunctive queries:
|
||||
|
||||
```
|
||||
prolog> ?- member([X,X],[a,b,c,[d,d],[e,d]]), member(X, [a,b,c,d,e,f,g]), member(Y, [X, a, b, c, d]).
|
||||
yes
|
||||
true
|
||||
Y = d
|
||||
X = d
|
||||
Press ; to continue or . to abort.
|
||||
X = d ;
|
||||
Y = a
|
||||
X = d
|
||||
Press ; to continue or . to abort.
|
||||
X = d ;
|
||||
Y = b
|
||||
X = d
|
||||
Press ; to continue or . to abort.
|
||||
X = d ;
|
||||
Y = c
|
||||
X = d
|
||||
Press ; to continue or . to abort.
|
||||
X = d ;
|
||||
Y = d
|
||||
X = d
|
||||
Press ; to continue or . to abort.
|
||||
no
|
||||
X = d ;
|
||||
false.
|
||||
prolog>
|
||||
```
|
||||
|
||||
@@ -114,6 +102,6 @@ term to a string results in an infinite loop, ie.
|
||||
```
|
||||
prolog> p(W, W).
|
||||
prolog> ?- p(f(f(W)), W).
|
||||
yes
|
||||
true
|
||||
*loops to infinity*
|
||||
```
|
||||
@@ -24,7 +24,7 @@ pub enum VarStatus {
|
||||
}
|
||||
|
||||
// Perm: 0 initially, a stack register once processed.
|
||||
// Temp: labeled with chunk_num and temp offset (unassigned if 0), arg (0 if unassigned).
|
||||
// Temp: labeled with chunk_num and temp offset (unassigned if 0).
|
||||
pub enum VarData {
|
||||
Perm(usize), Temp(usize, usize, TempVarData)
|
||||
}
|
||||
|
||||
@@ -304,49 +304,53 @@ Each predicate must have the same name and arity.";
|
||||
pub fn print(wam: &mut Machine, result: EvalSession) {
|
||||
match result {
|
||||
EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
|
||||
println!("yes");
|
||||
println!("true");
|
||||
|
||||
if heap_locs.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
'outer: loop {
|
||||
loop {
|
||||
let mut result = EvalSession::QueryFailure;
|
||||
let bindings = wam.heap_view(&heap_locs);
|
||||
|
||||
let stdin = stdin();
|
||||
let mut stdout = stdout().into_raw_mode().unwrap();
|
||||
|
||||
write!(stdout, "{}\n\r", bindings).unwrap();
|
||||
write!(stdout, "{}", bindings).unwrap();
|
||||
stdout.flush().unwrap();
|
||||
|
||||
if !wam.or_stack_is_empty() {
|
||||
write!(stdout, "Press ; to continue or . to abort.\n\r").unwrap();
|
||||
stdout.flush().unwrap();
|
||||
|
||||
for c in stdin.keys() {
|
||||
match c.unwrap() {
|
||||
Key::Char(';') => {
|
||||
write!(stdout, " ;\n\r").unwrap();
|
||||
result = wam.continue_query(&alloc_locs, &mut heap_locs);
|
||||
break;
|
||||
},
|
||||
Key::Char('.') =>
|
||||
break 'outer,
|
||||
Key::Char('.') => {
|
||||
write!(stdout, " .\n\r").unwrap();
|
||||
return;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if let &EvalSession::QueryFailure = &result {
|
||||
write!(stdout, "no\n\r").unwrap();
|
||||
write!(stdout, "false.\n\r").unwrap();
|
||||
stdout.flush().unwrap();
|
||||
break;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
write!(stdout(), ".\n").unwrap();
|
||||
},
|
||||
EvalSession::QueryFailure => println!("no"),
|
||||
EvalSession::QueryFailure => println!("false."),
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -306,10 +306,6 @@ impl Machine {
|
||||
-> EvalSession
|
||||
{
|
||||
if !self.or_stack_is_empty() {
|
||||
if self.ms.b == 0 {
|
||||
return EvalSession::QueryFailure;
|
||||
}
|
||||
|
||||
let b = self.ms.b - 1;
|
||||
self.ms.p = self.ms.or_stack[b].bp;
|
||||
|
||||
@@ -386,7 +382,7 @@ impl Machine {
|
||||
}
|
||||
|
||||
pub fn or_stack_is_empty(&self) -> bool {
|
||||
self.ms.or_stack.is_empty()
|
||||
self.ms.b == 0
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
|
||||
Reference in New Issue
Block a user