Closed guregu closed 1 month ago
Thanks for the fix, looks better now. I don't see any leaks now.
Here's another thing I found, maybe this is the issue I've been seeing with 32-bit wasm. I've been trying to reduce as much as possible and this is what I've gotten it down to so far.
% weird.pl
:- use_module(library(clpz)).
my_cool_predicate(
panel(FooWidth),
panel(BarWidth),
panel(BazWidth, Count)
) :-
Columns = 3,
BarWidth = 2600,
constraint_a(FooWidth),
constraint_b(BazWidth, Count),
SubSection #= BazWidth * (Columns - 1) + BarWidth * Columns,
10000 #= FooWidth * 2 + SubSection.
constraint_a(X) :-
X #=< 1300,
X #>= 230.
constraint_b(X, Count) :-
X0 #=< 1300,
X0 #>= 700,
X0 mod 100 #= 0,
Count in 1 .. sup,
X #= X0 * Count.
Some invalid writes/reads can be triggered by this query:
?- my_cool_predicate(panel(A),panel(C),panel(D, E)).
Valgrind logs:
$ valgrind --leak-check=full ./tpl weird.pl -g 'my_cool_predicate(panel(A),panel(C),panel(D, E))'
==24237== Memcheck, a memory error detector
==24237== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==24237== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==24237== Command: ../tpl-linux2 weird.pl -g my_cool_predicate(panel(A),panel(C),panel(D,\ E))
==24237==
==24237== Invalid write of size 8
==24237== at 0x232AB0: copy_vars (heap.c:401)
==24237== by 0x232DD7: deep_copy_to_tmp_with_replacement (heap.c:465)
==24237== by 0x232ED7: deep_copy_to_heap (heap.c:492)
==24237== by 0x18FE6B: do_duplicate_term (bif_predicates.c:1974)
==24237== by 0x18FF5B: bif_duplicate_term_2 (bif_predicates.c:1999)
==24237== by 0x283CE7: start (query.c:1626)
==24237== by 0x28BD13: dump_vars (toplevel.c:491)
==24237== by 0x28448B: start (query.c:1729)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237== Address 0x7a52ec8 is 56 bytes inside a block of size 2,400 free'd
==24237== at 0x488A1E4: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230E63: alloc_grow (heap.c:39)
==24237== by 0x23111F: alloc_on_tmp (heap.c:105)
==24237== by 0x23165B: deep_clone2_to_tmp (heap.c:206)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== Block was alloc'd at
==24237== at 0x48850E8: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230F67: init_tmp_heap (heap.c:70)
==24237== by 0x23240F: clone_to_heap (heap.c:305)
==24237== by 0x281ABB: find_key (query.c:1132)
==24237== by 0x282E0B: match_head (query.c:1451)
==24237== by 0x2840F3: start (query.c:1678)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237==
==24237== Invalid read of size 8
==24237== at 0x232AB8: copy_vars (heap.c:402)
==24237== by 0x232DD7: deep_copy_to_tmp_with_replacement (heap.c:465)
==24237== by 0x232ED7: deep_copy_to_heap (heap.c:492)
==24237== by 0x18FE6B: do_duplicate_term (bif_predicates.c:1974)
==24237== by 0x18FF5B: bif_duplicate_term_2 (bif_predicates.c:1999)
==24237== by 0x283CE7: start (query.c:1626)
==24237== by 0x28BD13: dump_vars (toplevel.c:491)
==24237== by 0x28448B: start (query.c:1729)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237== Address 0x7a52ec8 is 56 bytes inside a block of size 2,400 free'd
==24237== at 0x488A1E4: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230E63: alloc_grow (heap.c:39)
==24237== by 0x23111F: alloc_on_tmp (heap.c:105)
==24237== by 0x23165B: deep_clone2_to_tmp (heap.c:206)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== Block was alloc'd at
==24237== at 0x48850E8: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230F67: init_tmp_heap (heap.c:70)
==24237== by 0x23240F: clone_to_heap (heap.c:305)
==24237== by 0x281ABB: find_key (query.c:1132)
==24237== by 0x282E0B: match_head (query.c:1451)
==24237== by 0x2840F3: start (query.c:1678)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237==
==24237== Invalid read of size 4
==24237== at 0x232EF4: deep_copy_to_heap (heap.c:494)
==24237== by 0x18FE6B: do_duplicate_term (bif_predicates.c:1974)
==24237== by 0x18FF5B: bif_duplicate_term_2 (bif_predicates.c:1999)
==24237== by 0x283CE7: start (query.c:1626)
==24237== by 0x28BD13: dump_vars (toplevel.c:491)
==24237== by 0x28448B: start (query.c:1729)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237== Address 0x7a52e94 is 4 bytes inside a block of size 2,400 free'd
==24237== at 0x488A1E4: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230E63: alloc_grow (heap.c:39)
==24237== by 0x23111F: alloc_on_tmp (heap.c:105)
==24237== by 0x23165B: deep_clone2_to_tmp (heap.c:206)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== Block was alloc'd at
==24237== at 0x48850E8: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230F67: init_tmp_heap (heap.c:70)
==24237== by 0x23240F: clone_to_heap (heap.c:305)
==24237== by 0x281ABB: find_key (query.c:1132)
==24237== by 0x282E0B: match_head (query.c:1451)
==24237== by 0x2840F3: start (query.c:1678)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237==
==24237== Invalid read of size 4
==24237== at 0x232F20: deep_copy_to_heap (heap.c:496)
==24237== by 0x18FE6B: do_duplicate_term (bif_predicates.c:1974)
==24237== by 0x18FF5B: bif_duplicate_term_2 (bif_predicates.c:1999)
==24237== by 0x283CE7: start (query.c:1626)
==24237== by 0x28BD13: dump_vars (toplevel.c:491)
==24237== by 0x28448B: start (query.c:1729)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237== Address 0x7a52e94 is 4 bytes inside a block of size 2,400 free'd
==24237== at 0x488A1E4: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230E63: alloc_grow (heap.c:39)
==24237== by 0x23111F: alloc_on_tmp (heap.c:105)
==24237== by 0x23165B: deep_clone2_to_tmp (heap.c:206)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== Block was alloc'd at
==24237== at 0x48850E8: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230F67: init_tmp_heap (heap.c:70)
==24237== by 0x23240F: clone_to_heap (heap.c:305)
==24237== by 0x281ABB: find_key (query.c:1132)
==24237== by 0x282E0B: match_head (query.c:1451)
==24237== by 0x2840F3: start (query.c:1678)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237==
==24237== Invalid read of size 8
==24237== at 0x23099C: dup_cells (internal.h:999)
==24237== by 0x232F33: deep_copy_to_heap (heap.c:496)
==24237== by 0x18FE6B: do_duplicate_term (bif_predicates.c:1974)
==24237== by 0x18FF5B: bif_duplicate_term_2 (bif_predicates.c:1999)
==24237== by 0x283CE7: start (query.c:1626)
==24237== by 0x28BD13: dump_vars (toplevel.c:491)
==24237== by 0x28448B: start (query.c:1729)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237== Address 0x7a52e90 is 0 bytes inside a block of size 2,400 free'd
==24237== at 0x488A1E4: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230E63: alloc_grow (heap.c:39)
==24237== by 0x23111F: alloc_on_tmp (heap.c:105)
==24237== by 0x23165B: deep_clone2_to_tmp (heap.c:206)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== Block was alloc'd at
==24237== at 0x48850E8: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230F67: init_tmp_heap (heap.c:70)
==24237== by 0x23240F: clone_to_heap (heap.c:305)
==24237== by 0x281ABB: find_key (query.c:1132)
==24237== by 0x282E0B: match_head (query.c:1451)
==24237== by 0x2840F3: start (query.c:1678)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237==
==24237== Invalid read of size 8
==24237== at 0x2309A4: dup_cells (internal.h:999)
==24237== by 0x232F33: deep_copy_to_heap (heap.c:496)
==24237== by 0x18FE6B: do_duplicate_term (bif_predicates.c:1974)
==24237== by 0x18FF5B: bif_duplicate_term_2 (bif_predicates.c:1999)
==24237== by 0x283CE7: start (query.c:1626)
==24237== by 0x28BD13: dump_vars (toplevel.c:491)
==24237== by 0x28448B: start (query.c:1729)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237== Address 0x7a52ea0 is 16 bytes inside a block of size 2,400 free'd
==24237== at 0x488A1E4: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230E63: alloc_grow (heap.c:39)
==24237== by 0x23111F: alloc_on_tmp (heap.c:105)
==24237== by 0x23165B: deep_clone2_to_tmp (heap.c:206)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== Block was alloc'd at
==24237== at 0x48850E8: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230F67: init_tmp_heap (heap.c:70)
==24237== by 0x23240F: clone_to_heap (heap.c:305)
==24237== by 0x281ABB: find_key (query.c:1132)
==24237== by 0x282E0B: match_head (query.c:1451)
==24237== by 0x2840F3: start (query.c:1678)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237==
==24237== Invalid read of size 2
==24237== at 0x2309B0: dup_cells (internal.h:1000)
==24237== by 0x232F33: deep_copy_to_heap (heap.c:496)
==24237== by 0x18FE6B: do_duplicate_term (bif_predicates.c:1974)
==24237== by 0x18FF5B: bif_duplicate_term_2 (bif_predicates.c:1999)
==24237== by 0x283CE7: start (query.c:1626)
==24237== by 0x28BD13: dump_vars (toplevel.c:491)
==24237== by 0x28448B: start (query.c:1729)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237== Address 0x7a52e92 is 2 bytes inside a block of size 2,400 free'd
==24237== at 0x488A1E4: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230E63: alloc_grow (heap.c:39)
==24237== by 0x23111F: alloc_on_tmp (heap.c:105)
==24237== by 0x23165B: deep_clone2_to_tmp (heap.c:206)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2322AB: deep_clone2_to_tmp (heap.c:284)
==24237== by 0x2319FF: deep_clone2_to_tmp (heap.c:231)
==24237== Block was alloc'd at
==24237== at 0x48850E8: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==24237== by 0x230F67: init_tmp_heap (heap.c:70)
==24237== by 0x23240F: clone_to_heap (heap.c:305)
==24237== by 0x281ABB: find_key (query.c:1132)
==24237== by 0x282E0B: match_head (query.c:1451)
==24237== by 0x2840F3: start (query.c:1678)
==24237== by 0x28478B: execute (query.c:1836)
==24237== by 0x25A2A3: run (parser.c:4043)
==24237== by 0x277D87: pl_eval (prolog.c:144)
==24237== by 0x1187DF: main (tpl.c:304)
==24237==
C = 2600, E = 1, clpz:(D*2#=_A), clpz:(_B*2#=_C), clpz:(_C+7800#=_D), clpz:(_E+7800#=_F), clpz:(2*A+_G#=10000), clpz:(2*_H+_F#=10000), clpz:(D mod 100#=0), clpz:(A in 300..400), clpz:(D in 700..800), clpz:(_F in 9200..9400), clpz:(_C in 1400..1600).
?- halt.
==24237==
==24237== HEAP SUMMARY:
==24237== in use at exit: 232,023 bytes in 234 blocks
==24237== total heap usage: 490,680 allocs, 490,446 frees, 2,457,607,920 bytes allocated
==24237==
==24237== LEAK SUMMARY:
==24237== definitely lost: 0 bytes in 0 blocks
==24237== indirectly lost: 0 bytes in 0 blocks
==24237== possibly lost: 0 bytes in 0 blocks
==24237== still reachable: 232,023 bytes in 234 blocks
==24237== suppressed: 0 bytes in 0 blocks
==24237== Reachable blocks (those to which a pointer was found) are not shown.
==24237== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==24237==
==24237== For lists of detected and suppressed errors, rerun with: -s
==24237== ERROR SUMMARY: 16 errors from 7 contexts (suppressed: 0 from 0)
(This log is from running a 64-bit Linux VM)
This probably doesn't help, but I did a trace of 64-bit native ARM (left, good example) vs. 32-bit wasm (right, bad example) for the first simpler program I posted. The highlighted lines are when they appear to diverge. Left side finished after 2687 lines of trace, right side OOM'd after 2599554. Interestingly the right side never calls cyclic_term at all. (I don't think it's necessarily related to cyclic_term, but it's odd that they diverged).
Thank you, looks better now. The cause of my clpz troubles seems to be something else. I will continue to poke at it.
Hmm, I can kind of understand the symptoms I'm seeing now. Basically the 32-bit (wasm) version gets stuck in a loop of adding propagator(scalar_product_eq([1,-1] ...)
to the queue, which makes me wonder if maybe the enable/disable queue stuff is acting funny. However, the 64-bit version doesn't call this at all, it uses the pplus propagator and ends quickly.
I wonder if non-wasm 32-bit versions also exhibit this behavior.
?- use_module(library(clpz)).
true.
?- A #= B + 2, B #= 1.
throw(error(resource_error(memory),put_atts/2)).
I did 32-bit build of Trealla on Ubuntu:
~/trealla (devel) $ make OPT=-m32 NOFFI=1 NOSSL=1 ISOCLINE=1 ~/trealla (devel) $ file tpl tpl: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=35d1963133a777e99a9a2bf5f08b65360e1b625a, for GNU/Linux 3.2.0, not stripped ~/trealla (devel) $ ./tpl ?- use_module(library(clpz)). true. ?- A #= B + 2, B #= 1. A = 3, B = 1. ?- ~/trealla (devel) $
On Fri, Aug 2, 2024 at 1:30 PM guregu @.***> wrote:
Hmm, I can kind of understand the symptoms I'm seeing now. Basically the 32-bit (wasm) version gets stuck in a loop of adding propagator(scalar_product_eq([1,-1] ...) to the queue, which makes me wonder if maybe the enable/disable queue stuff is acting funny. However, the 64-bit version doesn't call this at all, it uses the pplus propagator and ends quickly. I wonder if non-wasm 32-bit versions also exhibit this behavior.
?- use_module(library(clpz)). true. ?- A #= B + 2, B #= 1. throw(error(resource_error(memory),put_atts/2)).
— Reply to this email directly, view it on GitHub https://github.com/trealla-prolog/trealla/issues/575#issuecomment-2264446820, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFNKSET74MU66WXAC7QVUM3ZPL4MJAVCNFSM6AAAAABLZPCBRGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENRUGQ2DMOBSGA . You are receiving this because you commented.Message ID: @.***>
Nice, that is good news. Likely some wasm weirdness afoot. I'll see if I can isolate it further
I've made some discoveries!
First one is that I'm dumb and was comparing a debug and non-debug build. Second is that the issue can be reduced to A #= B
which is much easier to see the issue.
The problem seems to be that the clauses in clpz_equal_/2
are in different orders. This leads the wasm build to execute the wrong instructions and get stuck. We can verify this easily with clpz:listing(clpz_equal_/2)
, yay.
Now the question is why they are jumbled up in the wasm build. One of the few differences is the qsort implementation, but not sure if relevant. I think we're close to the answer though.
?- use_module(library(clpz)).
true.
?- clpz:listing(clpz_equal_/2).
clpz_equal_(A,B) :-
cyclic_term(A)->domain_error(clpz_expression,A);cyclic_term(B)->domain_error(clpz_expression,B);false.
clpz_equal_(A,B) :-
(((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),(nonvar(B),(B= ?E;B= #E)->must_be_fd_integer(E),F=E;v_or_i(B),F=B)),true),!) , constrain_to_integer(D)),D=F.
clpz_equal_(A,B) :-
(((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E+F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(H,J,D,K),L)),new_queue(M)),phrase(init_propagator_([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),trigger_once_(L,N).
clpz_equal_(A,B) :-
(((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E+F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(H,J,D,K),L)),new_queue(M)),phrase(init_propagator_([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),trigger_once_(L,N).
clpz_equal_(A,B) :-
(((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E-F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(D,J,H,K),L)),new_queue(M)),phrase(init_propagator_([D,J,H],L),[M],[N])),variables_same_queue([D,J,H])),trigger_once_(L,N).
clpz_equal_(A,B) :-
(((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E-F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(D,J,H,K),L)),new_queue(M)),phrase(init_propagator_([D,J,H],L),[M],[N])),variables_same_queue([D,J,H])),trigger_once_(L,N).
clpz_equal_(A,B) :-
(((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E*F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(ptimes(H,J,D,K),L)),new_queue(M)),phrase(init_propagator_([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),trigger_once_(L,N).
clpz_equal_(A,B) :-
(((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E*F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(ptimes(H,J,D,K),L)),new_queue(M)),phrase(init_propagator_([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),trigger_once_(L,N).
clpz_equal_(A,B) :-
((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B= -E),(nonvar(E),(E= ?F;E= #F)->must_be_fd_integer(F),G=F;v_or_i(E),G=E)),true),!) , make_propagator(pplus(D,G,0,H),I)),new_queue(J)),phrase(init_propagator_([D,G],I),[J],[K])),variables_same_queue([D,G])),trigger_once_(I,K).
clpz_equal_(A,B) :-
((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A= -E),(nonvar(E),(E= ?F;E= #F)->must_be_fd_integer(F),G=F;v_or_i(E),G=E)),true),!) , make_propagator(pplus(D,G,0,H),I)),new_queue(J)),phrase(init_propagator_([D,G],I),[J],[K])),variables_same_queue([D,G])),trigger_once_(I,K).
clpz_equal_(A,B) :-
(((C=A,D=B),left_right_linsum_const(C,D,E,F,G)),!) , scalar_product_(#=,E,F,G).
clpz_equal_(A,B) :-
((((((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E+F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(init_propagator_([D,K],L),[M],[N])),variables_same_queue([D,K])),trigger_once_(L,N).
clpz_equal_(A,B) :-
((((((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E+F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(init_propagator_([D,K],L),[M],[N])),variables_same_queue([D,K])),trigger_once_(L,N).
clpz_equal_(A,B) :-
((((((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E-F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(-J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(init_propagator_([D,K],L),[M],[N])),variables_same_queue([D,K])),trigger_once_(L,N).
clpz_equal_(A,B) :-
((((((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E-F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(-J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(init_propagator_([D,K],L),[M],[N])),variables_same_queue([D,K])),trigger_once_(L,N).
clpz_equal_(A,B) :-
((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),E=B),true),!) , parse_clpz(E,D).
clpz_equal_(A,B) :-
((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),E=A),true),!) , parse_clpz(E,D).
clpz_equal_(A,B) :-
((((C=A,D=B),true),!) , parse_clpz(C,E)),parse_clpz(D,E).
?- use_module(library(clpz)).
true.
?- clpz:listing(clpz_equal_/2).
clpz_equal_(A,B) :-
(((C=A,D=B),left_right_linsum_const(C,D,E,F,G)),!) , scalar_product_(#=,E,F,G).
clpz_equal_(A,B) :-
((((((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E+F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(init_propagator_([D,K],L),[M],[N])),variables_same_queue([D,K])),trigger_once_(L,N).
clpz_equal_(A,B) :-
((((((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E+F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(init_propagator_([D,K],L),[M],[N])),variables_same_queue([D,K])),trigger_once_(L,N).
clpz_equal_(A,B) :-
((((((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E-F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(-J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(init_propagator_([D,K],L),[M],[N])),variables_same_queue([D,K])),trigger_once_(L,N).
clpz_equal_(A,B) :-
((((((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E-F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(-J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(init_propagator_([D,K],L),[M],[N])),variables_same_queue([D,K])),trigger_once_(L,N).
clpz_equal_(A,B) :-
((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),E=B),true),!) , parse_clpz(E,D).
clpz_equal_(A,B) :-
cyclic_term(A)->domain_error(clpz_expression,A);cyclic_term(B)->domain_error(clpz_expression,B);false.
clpz_equal_(A,B) :-
((((C=A,D=B),true),!) , parse_clpz(C,E)),parse_clpz(D,E).
clpz_equal_(A,B) :-
((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),E=A),true),!) , parse_clpz(E,D).
clpz_equal_(A,B) :-
((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A= -E),(nonvar(E),(E= ?F;E= #F)->must_be_fd_integer(F),G=F;v_or_i(E),G=E)),true),!) , make_propagator(pplus(D,G,0,H),I)),new_queue(J)),phrase(init_propagator_([D,G],I),[J],[K])),variables_same_queue([D,G])),trigger_once_(I,K).
clpz_equal_(A,B) :-
(((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E+F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(H,J,D,K),L)),new_queue(M)),phrase(init_propagator_([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),trigger_once_(L,N).
clpz_equal_(A,B) :-
(((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E+F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(H,J,D,K),L)),new_queue(M)),phrase(init_propagator_([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),trigger_once_(L,N).
clpz_equal_(A,B) :-
(((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E-F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(D,J,H,K),L)),new_queue(M)),phrase(init_propagator_([D,J,H],L),[M],[N])),variables_same_queue([D,J,H])),trigger_once_(L,N).
clpz_equal_(A,B) :-
(((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E-F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(D,J,H,K),L)),new_queue(M)),phrase(init_propagator_([D,J,H],L),[M],[N])),variables_same_queue([D,J,H])),trigger_once_(L,N).
clpz_equal_(A,B) :-
(((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E*F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(ptimes(H,J,D,K),L)),new_queue(M)),phrase(init_propagator_([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),trigger_once_(L,N).
clpz_equal_(A,B) :-
(((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E*F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(ptimes(H,J,D,K),L)),new_queue(M)),phrase(init_propagator_([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),trigger_once_(L,N).
clpz_equal_(A,B) :-
((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B= -E),(nonvar(E),(E= ?F;E= #F)->must_be_fd_integer(F),G=F;v_or_i(E),G=E)),true),!) , make_propagator(pplus(D,G,0,H),I)),new_queue(J)),phrase(init_propagator_([D,G],I),[J],[K])),variables_same_queue([D,G])),trigger_once_(I,K).
clpz_equal_(A,B) :-
(((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),(nonvar(B),(B= ?E;B= #E)->must_be_fd_integer(E),F=E;v_or_i(B),F=B)),true),!) , constrain_to_integer(D)),D=F.
true.
[0:user:8:f0:fp1:cp1:sp3:hp9:tp1] EXIT trace
[0:user:9:f0:fp1:cp1:sp3:hp9:tp1] CALL _1#=_2
[0:clpz:10:f1:fp2:cp1:sp5:hp9:tp1] EXIT _1#=_2
[0:clpz:11:f1:fp2:cp1:sp5:hp9:tp1] CALL clpz_equal(_1,_2)
[0:clpz:12:f2:fp3:cp1:sp7:hp9:tp1] EXIT clpz_equal(_1,_2)
[0:clpz:13:f2:fp3:cp1:sp7:hp9:tp1] CALL clpz_equal_(_1,_2),reinforce(_1)
[0:clpz:14:f2:fp3:cp1:sp7:hp9:tp1] CALL clpz_equal_(_1,_2)
[0:clpz:15:f3:fp4:cp2:sp197:hp9:tp1] EXIT clpz_equal_(_1,_2)
[0:clpz:16:f3:fp4:cp2:sp197:hp9:tp1] CALL (((_9=_1,_10=_2),left_right_linsum_const(_9,_10,_11,_12,_13)),!) , scalar_product_(#=,_11,_12,_13)
[0:clpz:17:f3:fp4:cp2:sp197:hp9:tp1] CALL ((_9=_1,_10=_2),left_right_linsum_const(_9,_10,_11,_12,_13)),!
[0:clpz:18:f3:fp4:cp2:sp197:hp9:tp1] CALL (_9=_1,_10=_2),left_right_linsum_const(_9,_10,_11,_12,_13)
[0:clpz:19:f3:fp4:cp2:sp197:hp9:tp1] CALL _9=_1,_10=_2
[0:clpz:20:f3:fp4:cp2:sp197:hp9:tp1] CALL _9=_1
[0:clpz:21:f3:fp4:cp2:sp197:hp9:tp2] EXIT _1=_1
[0:clpz:22:f3:fp4:cp2:sp197:hp9:tp2] CALL _10=_2
[0:clpz:23:f3:fp4:cp2:sp197:hp9:tp3] EXIT _2=_2
[0:clpz:24:f3:fp4:cp2:sp197:hp9:tp3] CALL left_right_linsum_const(_1,_2,_11,_12,_13)
[0:clpz:25:f4:fp5:cp2:sp213:hp9:tp3] EXIT left_right_linsum_const(_1,_2,_11,_12,_13)
[0:clpz:26:f4:fp5:cp2:sp213:hp9:tp3] CALL phrase(linsum(_1,0,_198),_199,_200),phrase(linsum(_2,0,_202),_203),maplist(linterm_negate,_203,_200),samsort(_199,_204),_204=[vn(_
205,_206)|_207],vns_coeffs_variables(_207,_206,_205,_208,_209),filter_linsum(_208,_209,_11,_12),_13 is _202-_198
[0:clpz:27:f4:fp5:cp2:sp213:hp9:tp3] CALL phrase(linsum(_1,0,_198),_199,_200)
[0:dcgs:28:f5:fp6:cp2:sp219:hp37:tp3] EXIT phrase(clpz:linsum(_1,0,_198),_199,_200)
[0:dcgs:29:f5:fp6:cp2:sp219:hp37:tp3] CALL strip_module(clpz:linsum(_1,0,_198),_214,_215),(var(clpz:linsum(_1,0,_198))->instantiation_error(phrase/3);nonvar(_215),dcg_const
r(_215),dcg_body(_215,_199,_200,_218)->call(_214:_218);call(_214:_215,_199,_200))
[0:dcgs:30:f5:fp6:cp2:sp219:hp37:tp3] CALL strip_module(clpz:linsum(_1,0,_198),_214,_215)
[0:dcgs:31:f5:fp6:cp2:sp219:hp37:tp5] EXIT strip_module(clpz:linsum(_1,0,_198),clpz,linsum(_1,0,_198))
[0:dcgs:32:f5:fp6:cp2:sp219:hp37:tp5] CALL var(clpz:linsum(_1,0,_198))->instantiation_error(phrase/3);nonvar(linsum(_1,0,_198)),dcg_constr(linsum(_1,0,_198)),dcg_body(linsu
m(_1,0,_198),_199,_200,_218)->call(clpz:_218);call(clpz:linsum(_1,0,_198),_199,_200)
[0:dcgs:33:f5:fp6:cp3:sp219:hp48:tp5] EXIT var(clpz:linsum(_1,0,_198))->instantiation_error(phrase/3);nonvar(linsum(_1,0,_198)),dcg_constr(linsum(_1,0,_198)),dcg_body(linsu
m(_1,0,_198),_199,_200,_218)->call(clpz:_218);call(clpz:linsum(_1,0,_198),_199,_200)
[0:dcgs:34:f5:fp6:cp3:sp219:hp48:tp5] CALL var(clpz:linsum(_1,0,_198))
( loops forever )
Interesting!
On Fri, 2 Aug 2024, 19:30 guregu, @.***> wrote:
I've made some discoveries!
First one is that I'm dumb and was comparing a debug and non-debug build. Second is that the issue can be reduced to A #= B which is much easier to see the issue.
The problem seems to be that the clauses in clpzequal/2 are in different orders. This leads the wasm build to execute the wrong instructions and get stuck. We can verify this easily with clpz:listing(clpzequal/2), yay.
Now the question is why they are jumbled up in the wasm build. One of the few differences is the qsort implementation, but not sure if relevant. I think we're close to the answer though. Good (native)
?- use_module(library(clpz)). true. ?- clpz:listing(clpzequal/2). clpzequal(A,B) :- cyclic_term(A)->domain_error(clpz_expression,A);cyclic_term(B)->domain_error(clpz_expression,B);false. clpzequal(A,B) :- (((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),(nonvar(B),(B= ?E;B= #E)->must_be_fd_integer(E),F=E;v_or_i(B),F=B)),true),!) , constrain_to_integer(D)),D=F. clpzequal(A,B) :- (((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E+F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(H,J,D,K),L)),new_queue(M)),phrase(initpropagator([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),triggeronce(L,N). clpzequal(A,B) :- (((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E+F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(H,J,D,K),L)),new_queue(M)),phrase(initpropagator([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),triggeronce(L,N). clpzequal(A,B) :- (((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E-F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(D,J,H,K),L)),new_queue(M)),phrase(initpropagator([D,J,H],L),[M],[N])),variables_same_queue([D,J,H])),triggeronce(L,N). clpzequal(A,B) :- (((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E-F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(D,J,H,K),L)),new_queue(M)),phrase(initpropagator([D,J,H],L),[M],[N])),variables_same_queue([D,J,H])),triggeronce(L,N). clpzequal(A,B) :- (((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=EF),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(ptimes(H,J,D,K),L)),new_queue(M)),phrase(initpropagator([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),triggeronce(L,N). clpzequal(A,B) :- (((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=EF),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(ptimes(H,J,D,K),L)),new_queue(M)),phrase(initpropagator([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),triggeronce(L,N). clpzequal(A,B) :- ((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B= -E),(nonvar(E),(E= ?F;E= #F)->must_be_fd_integer(F),G=F;v_or_i(E),G=E)),true),!) , make_propagator(pplus(D,G,0,H),I)),new_queue(J)),phrase(initpropagator([D,G],I),[J],[K])),variables_same_queue([D,G])),triggeronce(I,K). clpzequal(A,B) :- ((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A= -E),(nonvar(E),(E= ?F;E= #F)->must_be_fd_integer(F),G=F;v_or_i(E),G=E)),true),!) , make_propagator(pplus(D,G,0,H),I)),new_queue(J)),phrase(initpropagator([D,G],I),[J],[K])),variables_same_queue([D,G])),triggeronce(I,K). clpzequal(A,B) :- (((C=A,D=B),left_right_linsum_const(C,D,E,F,G)),!) , scalarproduct(#=,E,F,G). clpzequal(A,B) :- ((((((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E+F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(initpropagator([D,K],L),[M],[N])),variables_same_queue([D,K])),triggeronce(L,N). clpzequal(A,B) :- ((((((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E+F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(initpropagator([D,K],L),[M],[N])),variables_same_queue([D,K])),triggeronce(L,N). clpzequal(A,B) :- ((((((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E-F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(-J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(initpropagator([D,K],L),[M],[N])),variables_same_queue([D,K])),triggeronce(L,N). clpzequal(A,B) :- ((((((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E-F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(-J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(initpropagator([D,K],L),[M],[N])),variables_same_queue([D,K])),triggeronce(L,N). clpzequal(A,B) :- ((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),E=B),true),!) , parse_clpz(E,D). clpzequal(A,B) :- ((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),E=A),true),!) , parse_clpz(E,D). clpzequal(A,B) :- ((((C=A,D=B),true),!) , parse_clpz(C,E)),parse_clpz(D,E).
Bad (wasm)
?- use_module(library(clpz)). true. ?- clpz:listing(clpzequal/2). clpzequal(A,B) :- (((C=A,D=B),left_right_linsum_const(C,D,E,F,G)),!) , scalarproduct(#=,E,F,G). clpzequal(A,B) :- ((((((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E+F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(initpropagator([D,K],L),[M],[N])),variables_same_queue([D,K])),triggeronce(L,N). clpzequal(A,B) :- ((((((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E+F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(initpropagator([D,K],L),[M],[N])),variables_same_queue([D,K])),triggeronce(L,N). clpzequal(A,B) :- ((((((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E-F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(-J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(initpropagator([D,K],L),[M],[N])),variables_same_queue([D,K])),triggeronce(L,N). clpzequal(A,B) :- ((((((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E-F),nonvar(E)),E=abs(G)),(nonvar(G),(G= ?H;G= #H)->must_be_fd_integer(H),I=H;v_or_i(G),I=G)),J=F),D==I),!) , parse_clpz(-J,K)),make_propagator(x_eq_abs_plus_v(D,K),L)),new_queue(M)),phrase(initpropagator([D,K],L),[M],[N])),variables_same_queue([D,K])),triggeronce(L,N). clpzequal(A,B) :- ((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),E=B),true),!) , parse_clpz(E,D). clpzequal(A,B) :- cyclic_term(A)->domain_error(clpz_expression,A);cyclic_term(B)->domain_error(clpz_expression,B);false. clpzequal(A,B) :- ((((C=A,D=B),true),!) , parse_clpz(C,E)),parse_clpz(D,E). clpzequal(A,B) :- ((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),E=A),true),!) , parse_clpz(E,D). clpzequal(A,B) :- ((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A= -E),(nonvar(E),(E= ?F;E= #F)->must_be_fd_integer(F),G=F;v_or_i(E),G=E)),true),!) , make_propagator(pplus(D,G,0,H),I)),new_queue(J)),phrase(initpropagator([D,G],I),[J],[K])),variables_same_queue([D,G])),triggeronce(I,K). clpzequal(A,B) :- (((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E+F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(H,J,D,K),L)),new_queue(M)),phrase(initpropagator([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),triggeronce(L,N). clpzequal(A,B) :- (((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E+F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(H,J,D,K),L)),new_queue(M)),phrase(initpropagator([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),triggeronce(L,N). clpzequal(A,B) :- (((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=E-F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(D,J,H,K),L)),new_queue(M)),phrase(initpropagator([D,J,H],L),[M],[N])),variables_same_queue([D,J,H])),triggeronce(L,N). clpzequal(A,B) :- (((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=E-F),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(pplus(D,J,H,K),L)),new_queue(M)),phrase(initpropagator([D,J,H],L),[M],[N])),variables_same_queue([D,J,H])),triggeronce(L,N). clpzequal(A,B) :- (((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B=EF),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(ptimes(H,J,D,K),L)),new_queue(M)),phrase(initpropagator([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),triggeronce(L,N). clpzequal(A,B) :- (((((((((((nonvar(B),(B= ?C;B= #C)->must_be_fd_integer(C),D=C;v_or_i(B),D=B),nonvar(A)),A=EF),(nonvar(E),(E= ?G;E= #G)->must_be_fd_integer(G),H=G;v_or_i(E),H=E)),(nonvar(F),(F= ?I;F= #I)->must_be_fd_integer(I),J=I;v_or_i(F),J=F)),true),!) , make_propagator(ptimes(H,J,D,K),L)),new_queue(M)),phrase(initpropagator([H,J,D],L),[M],[N])),variables_same_queue([H,J,D])),triggeronce(L,N). clpzequal(A,B) :- ((((((((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),nonvar(B)),B= -E),(nonvar(E),(E= ?F;E= #F)->must_be_fd_integer(F),G=F;v_or_i(E),G=E)),true),!) , make_propagator(pplus(D,G,0,H),I)),new_queue(J)),phrase(initpropagator([D,G],I),[J],[K])),variables_same_queue([D,G])),triggeronce(I,K). clpzequal(A,B) :- (((((nonvar(A),(A= ?C;A= #C)->must_be_fd_integer(C),D=C;v_or_i(A),D=A),(nonvar(B),(B= ?E;B= #E)->must_be_fd_integer(E),F=E;v_or_i(B),F=B)),true),!) , constrain_to_integer(D)),D=F. true.
[0:user:8:f0:fp1:cp1:sp3:hp9:tp1] EXIT trace [0:user:9:f0:fp1:cp1:sp3:hp9:tp1] CALL _1#=_2 [0:clpz:10:f1:fp2:cp1:sp5:hp9:tp1] EXIT _1#=_2 [0:clpz:11:f1:fp2:cp1:sp5:hp9:tp1] CALL clpz_equal(_1,_2) [0:clpz:12:f2:fp3:cp1:sp7:hp9:tp1] EXIT clpz_equal(_1,_2) [0:clpz:13:f2:fp3:cp1:sp7:hp9:tp1] CALL clpzequal(_1,_2),reinforce(_1) [0:clpz:14:f2:fp3:cp1:sp7:hp9:tp1] CALL clpzequal(_1,_2) [0:clpz:15:f3:fp4:cp2:sp197:hp9:tp1] EXIT clpzequal(_1,_2) [0:clpz:16:f3:fp4:cp2:sp197:hp9:tp1] CALL (((_9=_1,_10=_2),left_right_linsum_const(_9,_10,_11,_12,_13)),!) , scalarproduct(#=,_11,_12,_13) [0:clpz:17:f3:fp4:cp2:sp197:hp9:tp1] CALL ((_9=_1,_10=_2),left_right_linsum_const(_9,_10,_11,_12,_13)),! [0:clpz:18:f3:fp4:cp2:sp197:hp9:tp1] CALL (_9=_1,_10=_2),left_right_linsum_const(_9,_10,_11,_12,_13) [0:clpz:19:f3:fp4:cp2:sp197:hp9:tp1] CALL _9=_1,_10=_2 [0:clpz:20:f3:fp4:cp2:sp197:hp9:tp1] CALL _9=_1 [0:clpz:21:f3:fp4:cp2:sp197:hp9:tp2] EXIT _1=_1 [0:clpz:22:f3:fp4:cp2:sp197:hp9:tp2] CALL _10=_2 [0:clpz:23:f3:fp4:cp2:sp197:hp9:tp3] EXIT _2=_2 [0:clpz:24:f3:fp4:cp2:sp197:hp9:tp3] CALL left_right_linsum_const(_1,_2,_11,_12,_13) [0:clpz:25:f4:fp5:cp2:sp213:hp9:tp3] EXIT left_right_linsum_const(_1,_2,_11,_12,_13) [0:clpz:26:f4:fp5:cp2:sp213:hp9:tp3] CALL phrase(linsum(_1,0,_198),_199,_200),phrase(linsum(_2,0,_202),_203),maplist(linterm_negate,_203,_200),samsort(_199,_204),204=[vn( 205,_206)|_207],vns_coeffs_variables(_207,_206,_205,_208,_209),filter_linsum(_208,_209,_11,_12),_13 is _202-_198 [0:clpz:27:f4:fp5:cp2:sp213:hp9:tp3] CALL phrase(linsum(_1,0,_198),_199,_200) [0:dcgs:28:f5:fp6:cp2:sp219:hp37:tp3] EXIT phrase(clpz:linsum(_1,0,_198),_199,_200) [0:dcgs:29:f5:fp6:cp2:sp219:hp37:tp3] CALL strip_module(clpz:linsum(_1,0,_198),_214,_215),(var(clpz:linsum(_1,0,_198))->instantiation_error(phrase/3);nonvar(_215),dcg_const r(_215),dcg_body(_215,_199,_200,_218)->call(_214:_218);call(_214:_215,_199,_200)) [0:dcgs:30:f5:fp6:cp2:sp219:hp37:tp3] CALL strip_module(clpz:linsum(_1,0,_198),_214,_215) [0:dcgs:31:f5:fp6:cp2:sp219:hp37:tp5] EXIT strip_module(clpz:linsum(_1,0,_198),clpz,linsum(_1,0,_198)) [0:dcgs:32:f5:fp6:cp2:sp219:hp37:tp5] CALL var(clpz:linsum(_1,0,_198))->instantiation_error(phrase/3);nonvar(linsum(_1,0,_198)),dcg_constr(linsum(_1,0,_198)),dcg_body(linsu m(_1,0,_198),_199,_200,_218)->call(clpz:_218);call(clpz:linsum(_1,0,_198),_199,_200) [0:dcgs:33:f5:fp6:cp3:sp219:hp48:tp5] EXIT var(clpz:linsum(_1,0,_198))->instantiation_error(phrase/3);nonvar(linsum(_1,0,_198)),dcg_constr(linsum(_1,0,_198)),dcg_body(linsu m(_1,0,_198),_199,_200,_218)->call(clpz:_218);call(clpz:linsum(_1,0,_198),_199,_200) [0:dcgs:34:f5:fp6:cp3:sp219:hp48:tp5] CALL var(clpz:linsum(_1,0,_198)) ( loops forever )
— Reply to this email directly, view it on GitHub https://github.com/trealla-prolog/trealla/issues/575#issuecomment-2264964265, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFNKSET6ZMBZNHCQXNYW5N3ZPNGUJAVCNFSM6AAAAABLZPCBRGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENRUHE3DIMRWGU . You are receiving this because you commented.Message ID: @.***>
Aha, I think it is qsort_r
after all. I figured out how to induce the problem in the normal native build. All you need to do is disable the native qsort_r impls and use the fallback one (sort_r_simple).
Good news: WASI's libc includes a qsort_r implementation that works :-) I will submit a small PR that fixes it
Thanks for the help! Glad to have this one figured out
Thanks for the help! Glad to have this one figured out
Thank you. There were some good fixes in there.
This seems to have introduced a use-after-free error as evidenced here...
valgrind tpl -g halt -f tests/tests/test096.pl
I'll look into it.
I noticed clpz usage in wasm trealla can sometimes OOM very easily, looks kinda like it gets stuck in a loop (tracing it vs. native 64-bit version shows that it runs for orders of magnitude more instructions before dying). While tracking that down I found a leak in copy_term/3 which may be related.
Here's a way to reproduce the leak: