diff options
author | Mark Thom <markjordanthom@gmail.com> | 2019-10-20 14:50:46 -0600 |
---|---|---|
committer | Mark Thom <markjordanthom@gmail.com> | 2019-10-20 14:50:46 -0600 |
commit | 1b1879a6fa348b7f79b9c81ddacd3e68ce46a115 (patch) | |
tree | fc0deb7614217833ddf5266bad4e40c036991aae | |
parent | 24e5e39c28ce16b48a14f11f16ffcaf3138d6094 (diff) |
fix attributed variables bug causing weighted_maximum/3 example to omit a variable bindingv0.8.115
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | README.md | 22 | ||||
-rw-r--r-- | src/prolog/lib/clpb.pl | 8 | ||||
-rw-r--r-- | src/prolog/lib/dif.pl | 3 | ||||
-rw-r--r-- | src/prolog/lib/freeze.pl | 1 | ||||
-rw-r--r-- | src/prolog/lib/lists.pl | 7 | ||||
-rw-r--r-- | src/prolog/machine/attributed_variables.rs | 15 | ||||
-rw-r--r-- | src/prolog/machine/machine_state_impl.rs | 8 | ||||
-rw-r--r-- | src/prolog/machine/mod.rs | 4 |
9 files changed, 44 insertions, 26 deletions
@@ -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" @@ -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) { |