Merge pull request #2812 from bakaq/attr_vars_arity_fix
Fix bug in finding arity for verify attributes
This commit is contained in:
@@ -563,30 +563,62 @@ impl Machine {
|
|||||||
self.machine_st.cp = self.machine_st.attr_var_init.cp;
|
self.machine_st.cp = self.machine_st.attr_var_init.cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut p = self.machine_st.p;
|
let p = self.machine_st.p;
|
||||||
let mut arity = 0;
|
|
||||||
|
|
||||||
while self.code[p].is_head_instr() {
|
// Find the boundaries of the current predicate
|
||||||
for r in self.code[p].registers() {
|
self.indices.code_dir.sort_by(|_, a, _, b| a.cmp(b));
|
||||||
if let RegType::Temp(t) = r {
|
|
||||||
arity = std::cmp::max(arity, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p += 1;
|
let predicate_idx = self
|
||||||
}
|
.indices
|
||||||
|
.code_dir
|
||||||
|
.binary_search_by_key(&p, |_, x| x.get().p() as usize)
|
||||||
|
.unwrap_or_else(|x| x - 1);
|
||||||
|
|
||||||
|
let current_pred_start = self
|
||||||
|
.indices
|
||||||
|
.code_dir
|
||||||
|
.get_index(predicate_idx)
|
||||||
|
.map(|x| x.1.p() as usize)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
debug_assert!(current_pred_start <= p);
|
||||||
|
|
||||||
|
let current_pred_end = self
|
||||||
|
.indices
|
||||||
|
.code_dir
|
||||||
|
.get_index(predicate_idx + 1)
|
||||||
|
.map(|x| x.1.p() as usize)
|
||||||
|
.unwrap_or(self.code.len());
|
||||||
|
|
||||||
|
debug_assert!(current_pred_end >= p);
|
||||||
|
debug_assert!(current_pred_end <= self.code.len());
|
||||||
|
|
||||||
|
// Find point to insert the interrupt
|
||||||
|
let p_interrupt = p + self.code[p..current_pred_end]
|
||||||
|
.iter()
|
||||||
|
.position(|x| !x.is_head_instr())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Scan registers of all instructions to find out how many to save
|
||||||
|
let arity = self.code[current_pred_start..current_pred_end]
|
||||||
|
.iter()
|
||||||
|
.flat_map(Instruction::registers)
|
||||||
|
.flat_map(|r| match r {
|
||||||
|
RegType::Temp(t) => Some(t),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.max()
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
let instr = std::mem::replace(
|
let instr = std::mem::replace(
|
||||||
&mut self.code[p],
|
&mut self.code[p_interrupt],
|
||||||
Instruction::VerifyAttrInterrupt(arity),
|
Instruction::VerifyAttrInterrupt(arity),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.code[VERIFY_ATTR_INTERRUPT_LOC] = instr;
|
self.code[VERIFY_ATTR_INTERRUPT_LOC] = instr;
|
||||||
self.machine_st.attr_var_init.cp = p;
|
self.machine_st.attr_var_init.cp = p_interrupt;
|
||||||
}
|
}
|
||||||
&Instruction::VerifyAttrInterrupt(arity) => {
|
&Instruction::VerifyAttrInterrupt(arity) => {
|
||||||
// let (_, arity) = self.code[VERIFY_ATTR_INTERRUPT_LOC].to_name_and_arity();
|
|
||||||
// let arity = std::cmp::max(arity, self.machine_st.num_of_args);
|
|
||||||
self.run_verify_attr_interrupt(arity);
|
self.run_verify_attr_interrupt(arity);
|
||||||
}
|
}
|
||||||
&Instruction::Add(ref a1, ref a2, t) => {
|
&Instruction::Add(ref a1, ref a2, t) => {
|
||||||
|
|||||||
17
tests/scryer/cli/issues/compilation_bug.in/a.pl
Normal file
17
tests/scryer/cli/issues/compilation_bug.in/a.pl
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
% Issue 2706
|
||||||
|
:- use_module(library(atts)).
|
||||||
|
:- use_module(library(lists)).
|
||||||
|
:- use_module(library(iso_ext)).
|
||||||
|
|
||||||
|
:- attribute a/1.
|
||||||
|
|
||||||
|
verify_attributes(_,_, []).
|
||||||
|
|
||||||
|
asdf([_|Xs], N) :-
|
||||||
|
true,
|
||||||
|
N1 is N - 1,
|
||||||
|
asdf(Xs, N1).
|
||||||
|
|
||||||
|
test_a :-
|
||||||
|
put_atts(A, a(1)),
|
||||||
|
call_with_inference_limit(asdf(A, 1), 1000, _).
|
||||||
30
tests/scryer/cli/issues/compilation_bug.in/b.pl
Normal file
30
tests/scryer/cli/issues/compilation_bug.in/b.pl
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
% Issue 2632
|
||||||
|
|
||||||
|
% Repro for cycle detection crash
|
||||||
|
:- use_module(library(lists)).
|
||||||
|
:- use_module(library(clpz)).
|
||||||
|
:- use_module(library(error)).
|
||||||
|
:- use_module(library(lambda)).
|
||||||
|
:- use_module(library(debug)).
|
||||||
|
|
||||||
|
clpz:monotonic.
|
||||||
|
|
||||||
|
q_r(T/N, T:U) :- 0 #=< #T, 0 #=< #U, #N #= T + U.
|
||||||
|
|
||||||
|
qs_Ts_Us(Qs, ΣTs, ΣUs) :-
|
||||||
|
maplist(\Q^T^U^(q_r(Q, T:U)), Qs, Ts, Us),
|
||||||
|
intlist_partsums(Ts, ΣTs),
|
||||||
|
intlist_partsums(Us, ΣUs).
|
||||||
|
|
||||||
|
%% Utility predicates used above:
|
||||||
|
|
||||||
|
intlist_partsums([X|Xs], [X|Ss]) :-
|
||||||
|
intlist_partsums_acc(Xs, Ss, X).
|
||||||
|
|
||||||
|
intlist_partsums_acc([], [], _).
|
||||||
|
intlist_partsums_acc([X|Xs], [S|Ss], A) :-
|
||||||
|
#S #= #X + #A,
|
||||||
|
intlist_partsums_acc(Xs, Ss, S).
|
||||||
|
|
||||||
|
test_b :-
|
||||||
|
once(qs_Ts_Us(_, [1,3], [5,9])).
|
||||||
19
tests/scryer/cli/issues/compilation_bug.in/c.pl
Normal file
19
tests/scryer/cli/issues/compilation_bug.in/c.pl
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
% Issue 2809
|
||||||
|
|
||||||
|
:- use_module(library(freeze)).
|
||||||
|
|
||||||
|
main1 :-
|
||||||
|
freeze(Minor,true),
|
||||||
|
cbor_minor_value1(Minor, []).
|
||||||
|
|
||||||
|
main2 :-
|
||||||
|
freeze(Minor,true),
|
||||||
|
cbor_minor_value2(Minor, []).
|
||||||
|
|
||||||
|
cbor_minor_value1(24, S0) :- numbytes_number(1, S0).
|
||||||
|
|
||||||
|
cbor_minor_value2(24, S0) :- S0=S1, numbytes_number(1, S1).
|
||||||
|
|
||||||
|
numbytes_number(_, []).
|
||||||
|
|
||||||
|
test_c :- main1.
|
||||||
2
tests/scryer/cli/issues/compilation_bug.stdin
Normal file
2
tests/scryer/cli/issues/compilation_bug.stdin
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
use_module(a), use_module(b), use_module(c).
|
||||||
|
\+ \+ (test_a, test_b, test_c).
|
||||||
2
tests/scryer/cli/issues/compilation_bug.stdout
Normal file
2
tests/scryer/cli/issues/compilation_bug.stdout
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
true.
|
||||||
|
true.
|
||||||
2
tests/scryer/cli/issues/compilation_bug.toml
Normal file
2
tests/scryer/cli/issues/compilation_bug.toml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# issue 2706
|
||||||
|
args = ["-f", "--no-add-history"]
|
||||||
Reference in New Issue
Block a user