fix attributed variables bug causing weighted_maximum/3 example to omit a variable binding

This commit is contained in:
Mark Thom
2019-10-20 14:50:46 -06:00
parent 24e5e39c28
commit 02eb66314e
9 changed files with 44 additions and 26 deletions

View File

@@ -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"

View File

@@ -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

View File

@@ -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),

View File

@@ -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(_)) }.

View File

@@ -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).

View File

@@ -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),

View File

@@ -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();

View File

@@ -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())
};
}

View File

@@ -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) {