summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Thom <markjordanthom@gmail.com>2019-10-20 14:50:46 -0600
committerMark Thom <markjordanthom@gmail.com>2019-10-20 14:50:46 -0600
commit1b1879a6fa348b7f79b9c81ddacd3e68ce46a115 (patch)
treefc0deb7614217833ddf5266bad4e40c036991aae
parent24e5e39c28ce16b48a14f11f16ffcaf3138d6094 (diff)
fix attributed variables bug causing weighted_maximum/3 example to omit a variable bindingv0.8.115
-rw-r--r--Cargo.toml2
-rw-r--r--README.md22
-rw-r--r--src/prolog/lib/clpb.pl8
-rw-r--r--src/prolog/lib/dif.pl3
-rw-r--r--src/prolog/lib/freeze.pl1
-rw-r--r--src/prolog/lib/lists.pl7
-rw-r--r--src/prolog/machine/attributed_variables.rs15
-rw-r--r--src/prolog/machine/machine_state_impl.rs8
-rw-r--r--src/prolog/machine/mod.rs4
9 files changed, 44 insertions, 26 deletions
diff --git a/Cargo.toml b/Cargo.toml
index c39d3b12..e770aea9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "scryer-prolog"
-version = "0.8.114"
+version = "0.8.115"
authors = ["Mark Thom <markjordanthom@gmail.com>"]
build = "build.rs"
repository = "https://github.com/mthom/scryer-prolog"
diff --git a/README.md b/README.md
index 57d71b1e..564c757c 100644
--- a/README.md
+++ b/README.md
@@ -93,7 +93,7 @@ strings.
First, install the latest stable version of
[Rust](https://www.rust-lang.org/en-US/install.html) using your
-preferred method. Then install the latest Scryer Prolog with cargo,
+preferred method. Then install Scryer Prolog with cargo,
like so:
```
@@ -101,13 +101,27 @@ $> cargo install scryer-prolog
```
cargo will download and install the libraries Scryer Prolog uses
-automatically. You can find the `scryer-prolog` executable in
-`~/.cargo/bin`.
+automatically from crates.io. You can find the `scryer-prolog`
+executable in `~/.cargo/bin`.
+
+Publishing Rust crates to crates.io and pushing to git are entirely
+distinct, independent processes, so to be sure you have the latest
+commit, it is recommended to clone directly from this git repository,
+which can be done as follows:
+
+```
+$> git clone https://github.com/mthom/scryer-prolog
+$> cd scryer-prolog
+$> cargo run [--release]
+```
+
+The optional `--release` flag will perform various optimizations,
+producing a faster executable.
Note on compatibility: Scryer Prolog should work on Linux, Mac OS X,
and BSD variants on which Rust runs. Windows support hinges on
rustyline and Termion being functional in that environment, which to
-my knowledge is not currently the case.
+my knowledge is not presently the case.
## Built-in predicates
diff --git a/src/prolog/lib/clpb.pl b/src/prolog/lib/clpb.pl
index d35b488c..2b140a72 100644
--- a/src/prolog/lib/clpb.pl
+++ b/src/prolog/lib/clpb.pl
@@ -1159,7 +1159,7 @@ labeling_var(V) :- V == 1, !.
labeling_var(V) :- domain_error(clpb_variable, V).
variables_in_index_order(Vs0, Vs) :-
- maplist(var_with_index, Vs0, IVs0),
+ maplist(var_with_index, Vs0, IVs0),
keysort(IVs0, IVs),
pairs_values(IVs, Vs).
@@ -1245,7 +1245,7 @@ bdd_count(Node, VNum, Count) :-
bdd_pow(Low, V, VNum, LPow),
bdd_pow(High, V, VNum, HPow),
Count0 is LPow*LCount + HPow*HCount,
- Count = Count0
+ Count0 = Count
)
).
@@ -1358,7 +1358,7 @@ weighted_maximum(Ws, Vars, Max) :-
pairs_values(IVs1, VarsIndexOrder),
% Pairs is a list of Var-Weight terms, in index order of Vars
pairs_keys_values(Pairs, VarsIndexOrder, WeightsIndexOrder),
- bdd_maximum(BDD, Pairs, Max),
+ bdd_maximum(BDD, Pairs, Max), %% A,B are in BDD, but not C; A,B,C *are* in Pairs.
max_labeling(BDD, Pairs).
max_labeling(1, Pairs) :- max_upto(Pairs, _, _).
@@ -1509,7 +1509,7 @@ max_variable_node(Node, V0-N0, V-N) :-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
ands_fusion(Ands0, Ands) :-
- maplist(with_variables, Ands0, Pairs0),
+ maplist(with_variables, Ands0, Pairs0),
keysort(Pairs0, Pairs),
group_pairs_by_key(Pairs, Groups),
pairs_values(Groups, Andss),
diff --git a/src/prolog/lib/dif.pl b/src/prolog/lib/dif.pl
index 77cfee57..347e9d13 100644
--- a/src/prolog/lib/dif.pl
+++ b/src/prolog/lib/dif.pl
@@ -51,4 +51,5 @@ gather_dif_goals([(X \== Y) | Goals]) -->
attribute_goals(X) -->
{ get_atts(X, +dif(Goals)) },
- gather_dif_goals(Goals).
+ gather_dif_goals(Goals),
+ { put_atts(X, -dif(_)) }.
diff --git a/src/prolog/lib/freeze.pl b/src/prolog/lib/freeze.pl
index 96e3dda5..049e024b 100644
--- a/src/prolog/lib/freeze.pl
+++ b/src/prolog/lib/freeze.pl
@@ -26,6 +26,7 @@ gather_freeze_goals(Attrs, _) -->
!.
gather_freeze_goals([frozen(X) | _], Var) -->
[freeze(Var, X)],
+ { put_atts(Var, -frozen(_)) },
!.
gather_freeze_goals([_ | Attrs], Var) -->
gather_freeze_goals(Attrs, Var).
diff --git a/src/prolog/lib/lists.pl b/src/prolog/lib/lists.pl
index c7d8e6a3..4fc5de96 100644
--- a/src/prolog/lib/lists.pl
+++ b/src/prolog/lib/lists.pl
@@ -3,6 +3,7 @@
maplist/4, maplist/5, maplist/6, maplist/7,
maplist/8, maplist/9]).
+
length(Xs, N) :-
var(N), !,
'$skip_max_list'(M, -1, Xs, Xs0),
@@ -30,17 +31,22 @@ length_rundown([_|Xs], N) :-
N1 is N-1,
length_rundown(Xs, N1).
+
member(X, [X|_]).
member(X, [_|Xs]) :- member(X, Xs).
+
select(X, [X|Xs], Xs).
select(X, [Y|Xs], [Y|Ys]) :- select(X, Xs, Ys).
+
append([], R, R).
append([X|L], R, [X|S]) :- append(L, R, S).
+
memberchk(X, Xs) :- member(X, Xs), !.
+
reverse(Xs, Ys) :-
( nonvar(Xs) -> reverse(Xs, Ys, [], Xs)
; reverse(Ys, Xs, [], Ys)
@@ -50,6 +56,7 @@ reverse([], [], YsRev, YsRev).
reverse([X1|Xs], [Y1|Ys], YsPreludeRev, Xss) :-
reverse(Xs, Ys, [Y1|YsPreludeRev], Xss).
+
maplist(_, []).
maplist(Cont1, [E1|E1s]) :-
call(Cont1, E1),
diff --git a/src/prolog/machine/attributed_variables.rs b/src/prolog/machine/attributed_variables.rs
index 638c403b..80fd11bc 100644
--- a/src/prolog/machine/attributed_variables.rs
+++ b/src/prolog/machine/attributed_variables.rs
@@ -131,24 +131,17 @@ impl MachineState {
}
pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
- let rs = MAX_ARITY;
-
- // store temp vars in perm vars slots along with self.b0 and
- // self.num_of_args. why self.b0? if we return to a NeckCut
- // after finishing the interrupt, it won't work correctly if
- // self.b == self.b0. we must change it back when we return,
- // as if nothing happened.
- self.allocate(rs + 2);
+ self.allocate(self.num_of_args + 2);
let e = self.e;
self.and_stack[e].interrupt_cp = self.attr_var_init.cp;
- for i in 1..rs + 1 {
+ for i in 1 .. self.num_of_args + 1 {
self.and_stack[e][i] = self[RegType::Temp(i)].clone();
}
- self.and_stack[e][rs + 1] = Addr::Con(Constant::Usize(self.b0));
- self.and_stack[e][rs + 2] = Addr::Con(Constant::Usize(self.num_of_args));
+ self.and_stack[e][self.num_of_args + 1] = Addr::Con(Constant::Usize(self.b0));
+ self.and_stack[e][self.num_of_args + 2] = Addr::Con(Constant::Usize(self.num_of_args));
self.verify_attributes();
diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs
index 32a06774..16495c1e 100644
--- a/src/prolog/machine/machine_state_impl.rs
+++ b/src/prolog/machine/machine_state_impl.rs
@@ -754,7 +754,7 @@ impl MachineState {
offset += 1;
} else {
self.trail[i - offset] = self.trail[i];
- },
+ },
TrailRef::Ref(Ref::StackCell(fr, _)) => {
let fr_gi = self.and_stack[fr].global_index;
let b_gi = if !self.or_stack.is_empty() {
@@ -775,7 +775,7 @@ impl MachineState {
self.tr -= offset;
self.trail.truncate(self.tr);
}
-
+
#[inline]
fn write_char_to_string(&mut self, s: &mut StringList, c: char) -> bool {
self.pstr_trail(s.clone());
@@ -3231,6 +3231,8 @@ impl MachineState {
)
),
};
+
+ self.last_call = false;
}
pub(super) fn execute_ctrl_instr(
@@ -3266,7 +3268,7 @@ impl MachineState {
self.b0 = self.b;
self.p += offset;
}
- &ControlInstruction::Proceed => self.p = CodePtr::Local(self.cp.clone()),
+ &ControlInstruction::Proceed => self.p = CodePtr::Local(self.cp.clone())
};
}
diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs
index 21ed9670..c8ea15c4 100644
--- a/src/prolog/machine/mod.rs
+++ b/src/prolog/machine/mod.rs
@@ -1112,12 +1112,12 @@ impl MachineState {
match self.p {
CodePtr::VerifyAttrInterrupt(_) => {
- self.p = CodePtr::Local(self.attr_var_init.cp);
+ self.p = CodePtr::Local(self.attr_var_init.cp);
let instigating_p = CodePtr::Local(self.attr_var_init.instigating_p);
let instigating_instr = code_repo.lookup_instr(false, &instigating_p).unwrap();
- if instigating_instr.as_ref().is_head_instr() {
+ if !instigating_instr.as_ref().is_head_instr() {
let cp = self.p.local();
self.run_verify_attr_interrupt(cp);
} else if !self.verify_attr_stepper(indices, policies, code_repo, prolog_stream) {