fix attributed variables bug causing weighted_maximum/3 example to omit a variable binding
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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(_)) }.
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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())
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user