mthom / scryer-prolog

A modern Prolog implementation written mostly in Rust.
BSD 3-Clause "New" or "Revised" License
2.08k stars 125 forks source link

Logtalk support #922

Closed pmoura closed 1 year ago

pmoura commented 3 years ago

The current Logtalk git version includes preliminary support for Scryer Prolog, including a scryerlgt shell script to start Logtalk. The script requires the current Scryer Prolog git version. For now, the main goal would be run Logtalk's standards compliance tests. But loading the lgtunit tool or a large example (e.g. searching) always ends with a crash (at least on macOS). To reproduce these crashes, after installing the current Logtalk git version, try:

$ scryerlgt.sh
...
?- {lgtunit(loader)}.
...

Or:

$ scryerlgt.sh
...
?- {searching(loader)}.
...

Not sure how much valuer is in the backtrace but I get:

thread 'main' panicked at 'internal error: entered unreachable code', src/machine/compile.rs:728:17
stack backtrace:
   0:        0x10de214fe - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h04abbaabf148650a
   1:        0x10de5d83e - core::fmt::write::h14dac7cadec1cc70
   2:        0x10de20e1a - std::io::Write::write_fmt::hfaf2e10dfdcc61d8
   3:        0x10de3e369 - std::panicking::default_hook::{{closure}}::h350fee0bf60f2674
   4:        0x10de3dedb - std::panicking::default_hook::h0b4e3bc46e6dcb8d
   5:        0x10de3e8fa - std::panicking::rust_panic_with_hook::h8cdc0a575f4a5a7b
   6:        0x10de21c99 - std::panicking::begin_panic_handler::{{closure}}::h7a7b30fd1c313876
   7:        0x10de21648 - std::sys_common::backtrace::__rust_end_short_backtrace::h2e099be83c81509d
   8:        0x10de3e473 - _rust_begin_unwind
   9:        0x10de7258f - core::panicking::panic_fmt::h4f63e4f6b62b650b
  10:        0x10de724e7 - core::panicking::panic::hb3c06f51e2e58141
  11:        0x10dbb328b - scryer_prolog::machine::compile::thread_choice_instr_at_to::h5ace4fd13a0b3d92
  12:        0x10dbb596a - scryer_prolog::machine::compile::append_compiled_clause::h3b427530b04d913a
  13:        0x10da8f06d - scryer_prolog::machine::compile::<impl scryer_prolog::machine::load_state::LoadState>::incremental_compile_clause::hbb760f797a9d1334
  14:        0x10daeb208 - scryer_prolog::machine::loader::<impl scryer_prolog::machine::Machine>::compile_assert::h4c72d8054cc4a1e3
  15:        0x10daf3bcc - scryer_prolog::machine::Machine::handle_toplevel_command::hcbc4d2457d98f1d8
  16:        0x10daed03f - scryer_prolog::machine::Machine::run_module_predicate::h665a482ee83b04f2
  17:        0x10daeddc0 - scryer_prolog::machine::Machine::run_top_level::h98ad3e5a02b065d9
  18:        0x10d9c3f5e - scryer_prolog::main::hd9ecefa6a4ac075a
  19:        0x10d9c83ca - std::sys_common::backtrace::__rust_begin_short_backtrace::h1cd4f2d4668f330b
  20:        0x10d9c83ec - std::rt::lang_start::{{closure}}::hd97e1ceb299400ab
  21:        0x10de430a0 - std::rt::lang_start_internal::hf4b96bfc8c02c8b0
  22:        0x10d9c40c9 - _main
mthom commented 3 years ago

I get the same crash.

pmoura commented 3 years ago

The crash with the searching example is similar:

thread 'main' panicked at 'internal error: entered unreachable code', src/machine/compile.rs:728:17
stack backtrace:
   0:        0x103bb34fe - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h04abbaabf148650a
   1:        0x103bef83e - core::fmt::write::h14dac7cadec1cc70
   2:        0x103bb2e1a - std::io::Write::write_fmt::hfaf2e10dfdcc61d8
   3:        0x103bd0369 - std::panicking::default_hook::{{closure}}::h350fee0bf60f2674
   4:        0x103bcfedb - std::panicking::default_hook::h0b4e3bc46e6dcb8d
   5:        0x103bd08fa - std::panicking::rust_panic_with_hook::h8cdc0a575f4a5a7b
   6:        0x103bb3c99 - std::panicking::begin_panic_handler::{{closure}}::h7a7b30fd1c313876
   7:        0x103bb3648 - std::sys_common::backtrace::__rust_end_short_backtrace::h2e099be83c81509d
   8:        0x103bd0473 - _rust_begin_unwind
   9:        0x103c0458f - core::panicking::panic_fmt::h4f63e4f6b62b650b
  10:        0x103c044e7 - core::panicking::panic::hb3c06f51e2e58141
  11:        0x10394528b - scryer_prolog::machine::compile::thread_choice_instr_at_to::h5ace4fd13a0b3d92
  12:        0x10394796a - scryer_prolog::machine::compile::append_compiled_clause::h3b427530b04d913a
  13:        0x10382106d - scryer_prolog::machine::compile::<impl scryer_prolog::machine::load_state::LoadState>::incremental_compile_clause::hbb760f797a9d1334
  14:        0x10387d208 - scryer_prolog::machine::loader::<impl scryer_prolog::machine::Machine>::compile_assert::h4c72d8054cc4a1e3
  15:        0x103885bcc - scryer_prolog::machine::Machine::handle_toplevel_command::hcbc4d2457d98f1d8
  16:        0x10387f03f - scryer_prolog::machine::Machine::run_module_predicate::h665a482ee83b04f2
  17:        0x10387fdc0 - scryer_prolog::machine::Machine::run_top_level::h98ad3e5a02b065d9
  18:        0x103755f5e - scryer_prolog::main::hd9ecefa6a4ac075a
  19:        0x10375a3ca - std::sys_common::backtrace::__rust_begin_short_backtrace::h1cd4f2d4668f330b
  20:        0x10375a3ec - std::rt::lang_start::{{closure}}::hd97e1ceb299400ab
  21:        0x103bd50a0 - std::rt::lang_start_internal::hf4b96bfc8c02c8b0
  22:        0x1037560c9 - _main
mthom commented 3 years ago

{lgtunit(loader)} appears to work after the latest commit but {searching(loader)} just hangs also seems to load correctly now.

pmoura commented 3 years ago

Same results here: both lgtunit and searching load fine. But trying to run the tests for the searching example (using the goal {searching(tester)}) crashes. Same with tests for a smaller example. E.g.

?- {ack(tester)}.
failing code: 

1984080 | dynamic_else 48338, inf, 142
1984081 | execute $lgt_ctg_super_call_nv/64039/3, 0
1984082 | retry_me_else 80
1984083 | get_structure $lgt_ctg_super_call_/3, X1
1984084 | unify_variable X3
1984085 | unify_variable X4
1984086 | unify_variable X5
1984087 | get_structure $lgt_ctg_super_call_nv/3, X2
1984088 | unify_value X3
1984089 | unify_value X4
1984090 | unify_value X5
1984091 | proceed
1984092 | dynamic_else 48339, inf, 0
1984093 | switch_on_term 1, IndexingCodePtr::DynamicExternal(17), IndexingCodePtr::Internal(1), IndexingCodePtr::Fail, IndexingCodePtr::Failswitch_on_constant 2dynamic(2)dynamic(142)
1984094 | dynamic_internal_else 48339, 48343, fail(0)
1984095 | get_constant user, A1
1984096 | get_value X2, A4
1984097 | get_constant true, A5
1984098 | execute true/5/0, 0
1984099 | retry_me_else 63
1984100 | get_structure $lgt_db_lookup_cache_/5, X1
1984101 | unify_constant user
1984102 | unify_variable X3
1984103 | unify_void 1
1984104 | unify_value X3
1984105 | unify_constant true
1984106 | get_constant true, A2
1984107 | proceed
1984108 | dynamic_else 48340, inf, 0
1984109 | rev_jmp_by 16
1984110 | dynamic_internal_else 48340, inf, 10
1984111 | get_constant tests, A1
1984112 | get_structure passed_/1, X2
1984113 | unify_variable X6
1984114 | get_constant lgtunit, A3
1984115 | get_structure $tests#0.passed_#1/2, X4
1984116 | unify_value X6
1984117 | unify_void 1
1984118 | get_constant true, A5
1984119 | execute true/5/0, 0
1984120 | rev_jmp_by 26
1984121 | rev_jmp_by 0
1984122 | try_me_else 0
1984123 | rev_jmp_by 1953401
1984124 | retry_me_else 14
1984125 | get_structure $lgt_db_lookup_cache_/5, X1
1984126 | unify_constant tests
1984127 | unify_variable X3
1984128 | unify_constant lgtunit
1984129 | unify_variable X4
1984130 | unify_constant true
1984131 | get_constant true, A2
1984132 | get_structure passed_/1, X3
1984133 | unify_variable X5
1984134 | get_structure $tests#0.passed_#1/2, X4
1984135 | unify_value X5
1984136 | unify_void 1
1984137 | proceed
1984138 | rev_jmp_by 152
1984139 | rev_jmp_by 0
1984140 | dynamic_else 48341, inf, 0
1984141 | switch_on_term 1, IndexingCodePtr::DynamicExternal(1), IndexingCodePtr::Internal(1), IndexingCodePtr::Fail, IndexingCodePtr::Failswitch_on_constant 3
1984142 | dynamic_internal_else 48341, inf, 0
1984143 | get_constant 0, A1
1984144 | execute true/5/0, 0
1984145 | try_me_else 0
1984146 | rev_jmp_by 1953424
1984147 | try_me_else 6
1984148 | get_structure $tests#0.passed_#1/2, X1
1984149 | unify_constant 0
1984150 | unify_void 1
1984151 | get_constant true, A2
1984152 | proceed
1984153 | rev_jmp_by 29
1984154 | rev_jmp_by 0
1984155 | dynamic_internal_else 48342, inf, fail(0)
1984156 | get_structure failed_/1, X1
1984157 | unify_variable X4
1984158 | get_structure $tests#0.failed_#1/2, X3
1984159 | unify_value X4
thread 'main' panicked at 'internal error: entered unreachable code', src/machine/compile.rs:742:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
✘-101 ~ 
pmoura commented 3 years ago

With that latest fix, I'm able to run the ack example tests both manually and automated:

?- {ack(tester)}.
% 
% tests started at 0-00-00, 00:00:00
% 
% running tests from object tests
% file: /Users/pmoura/logtalk/examples/ack/tests.lgt
% 
% ack_1: success (in 0.0 seconds)
% ack_2: success (in 0.0 seconds)
% ack_3: success (in 0.0 seconds)
% 
% 3 tests: 0 skipped, 3 passed, 0 failed
% completed tests from object tests
% 
% 
% clause coverage ratio and covered clauses per entity predicate
% 
% ack: ack/3 - 3/3 - (all)
% ack: 3 out of 3 clauses covered, 100.0% coverage
% 
% 1 entity declared as covered containing 3 clauses
% 1 out of 1 entity covered, 100.0% entity coverage
% 3 out of 3 clauses covered, 100.0% clause coverage
% 
% tests ended at 0-00-00, 00:00:00
% 
   true
;  ...
?- 

$ cd logtalk/examples/ack/
$ logtalk_tester -p scryer
% Batch testing started @ 2021-05-05 20:47:28
%         Logtalk version: 3.46.0-stable
%         Scryer Prolog version: 0.8.128
%
% logtalk/examples/ack
%         3 tests: 0 skipped, 3 passed, 0 failed
%         completed tests from object tests
%         clause coverage 100.0%
%
% 1 test sets: 1 completed, 0 skipped, 0 broken, 0 timeouts, 0 crashes
% 3 tests: 0 skipped, 3 passed, 0 failed
%
% Batch testing ended @ 2021-05-05 20:49:04

This is promising 🙂 But current Logtalk support for Scryer Prolog is a bit of a hack due to missing standard (ISO or de facto) predicates but specially a much more complete operating-system/file-system interface. I will open later a separate issue for the later.

mthom commented 3 years ago

I noticed some other issues with Logtalk on Scryer that are better addressed after I finish the new heap representation and add GC, since many of the currently problematic parts are being revamped anyway.

pmoura commented 3 years ago

Running all tests in the Logtalk distribution, I get:

$ cd logtalk
$ logtalk_tester -p scryer -g "set_logtalk_flag(clean,off)" -w -t 360
...
% 509 test sets: 374 completed, 93 skipped, 26 broken, 9 timeouts, 7 crashes
% 7919 tests: 2496 skipped, 4558 passed, 865 failed

Most of the test failures are caused by a small number of common issues. I will try to isolate and report them.

pmoura commented 3 years ago

One of the crashes is with the random library tests:


$ scryerlgt
...
?- {random(tester)}.
% 
% tests started at 0-00-00, 00:00:00
% 
% running tests from object tests(random)
% file: /Users/pmoura/logtalk/library/random/tests.lgt
% 
% random_random_1_01: success (in 0.0 seconds)
% random_between_3_01: success (in 0.0 seconds)
% random_between_3_02: success (in 0.0 seconds)
% random_member_2_01: success (in 0.0 seconds)
% random_select_3_01: success (in 0.0 seconds)
!     random_enumerate_2_01: failure (in 0.0 seconds)
!       quick check test failure (at test 1 after 0 shrinks with starting seed seed(3172,9814,20125)): random_enumerate_2([5,9,2,3,1,8,4,0,7,6,9,8,4,1,2,3,5,0,7,6,4,1,7,2,3,8,0,6,9,5,4,2,3,9,6,5,8,1,0,7,6,1,8,2,7,4,9,5,0,3,1,7,4,0,9,6,2,5,8,3,6,5,9,8,7,2,3,0,1,4,5,0,4,1,6,7,3,9,8,2,4,6,0,2,8,1,5,3,7,9,4,6,0,9,1,5,8,7,3,2,8,9,3,6,0,4,5,2,7,1,3,7,6,0,4,9,5,2,1,8,5,2,8,0,1,6,7,4,3,9,4,1,2,3,5,6,8,0,7,9,5,3,2,0,6,9,1,8,7,4,0,1,8,3,5,4,6,7,9,2,2,0,5,7,1,8,6,4,3,9,4,1,6,3,0,8,7,2,5,9,6,7,4,5,3,9,2,8,1,0,8,3,9,0,1,2,7,4,6,5,9,6,1,5,8,7,0,2,3,4,5,3,1,2,4,9,6,8,7,0,3,5,9,4,1,0,6,2,8,7,2,9,5,1,0,4,8,7,6,3,0,4,7,3,8,1,2,9,6,5,9,8,5,2,3,6,1,7,4,0,2,0,8,4,3,9,1,6,7,5,2,0,3,6,4,9,5,8,1,7,5,6,9,7,2,8,3,1,4,0,1,6,9,8,3,7,0,4,5,2,6,9,5,8,2,7,1,3,0,4,8,0,9,6,3,5,7,1,2,4,2,8,7,1,3,0,5,4,9,6,8,1,0,6,7,9,3,2,5,4,5,3,1,2,9,0,4,7,8,6,1,4,6,5,3,0,9,2,7,8,1,3,7,4,8,0,5,2,6,9,4,0,2,8,7,6,1,5,3,9,2,4,5,3,6,8,9,7,1,0,7,9,8,5,3,1,4,0,2,6,5,9,2,0,3,6,8,1,7,4,3,7,5,2,9,4,1,0,8,6,2,6,4,0,1,3,7,9,8,5,3,4,6,8,0,7,5,2,1,9,3,1,8,7,0,9,2,5,6,4,9,8,2,1,6,0,4,3,7,5,8,5,6,9,2,0,3,7,1,4,4,8,3,6,2,0,9,5,7,1,0,1,9,3,7,8,5,6,4,2,0,6,1,8,7,5,9,2,4,3,9,2,7,8,0,1,6,4,3,5,4,3,2,5,8,1,9,0,7,6,4,5,9,2,7,3,6,8,0,1,4,2,9,3,5,0,6,8,1,7,2,7,0,6,1,5,8,9,4,3,4,6,8,9,1,3,7,5,0,2,5,3,6,0,2,4,9,8,1,7])
!       in file /Users/pmoura/logtalk/library/random/tests.lgt at or above line -1
% random_permutation_2_01: success (in 0.0 seconds)
% random_sequence_4_01: success (in 0.0 seconds)
% random_sequence_4_02: success (in 0.0 seconds)
% random_sequence_4_03: success (in 0.0 seconds)
% random_sequence_4_04: success (in 0.0 seconds)
% random_set_4_01: success (in 0.0 seconds)
% random_set_4_02: success (in 0.0 seconds)
% random_set_4_03: success (in 0.0 seconds)
% random_set_4_04: success (in 0.0 seconds)
% random_set_4_05: success (in 0.0 seconds)
% random_set_4_06: success (in 0.0 seconds)
% random_get_seed_1_01: success (in 0.0 seconds)
% random_set_seed_1_01: success (in 0.0 seconds)
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: other (not out-of-memory)', /Users/pmoura/.cargo/registry/src/github.com-1ecc6299db9ec823/slice-deque-0.3.0/src/lib.rs:571:38
stack backtrace:
   0:        0x1083854fe - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h04abbaabf148650a
   1:        0x1083c183e - core::fmt::write::h14dac7cadec1cc70
   2:        0x108384e1a - std::io::Write::write_fmt::hfaf2e10dfdcc61d8
   3:        0x1083a2369 - std::panicking::default_hook::{{closure}}::h350fee0bf60f2674
   4:        0x1083a1edb - std::panicking::default_hook::h0b4e3bc46e6dcb8d
   5:        0x1083a28fa - std::panicking::rust_panic_with_hook::h8cdc0a575f4a5a7b
   6:        0x108385cc5 - std::panicking::begin_panic_handler::{{closure}}::h7a7b30fd1c313876
   7:        0x108385648 - std::sys_common::backtrace::__rust_end_short_backtrace::h2e099be83c81509d
   8:        0x1083a2473 - _rust_begin_unwind
   9:        0x1083d658f - core::panicking::panic_fmt::h4f63e4f6b62b650b
  10:        0x1083d60f5 - core::result::unwrap_failed::hc2a56d017349147e
  11:        0x107fea192 - <slice_deque::SliceDeque<T> as slice_deque::SpecExtend<T,I>>::spec_extend::hddbbbd4bff81b2af
  12:        0x108117b6a - scryer_prolog::machine::compile::prepend_compiled_clause::h4d54ac4a4038ba43
  13:        0x107ff3758 - scryer_prolog::machine::compile::<impl scryer_prolog::machine::load_state::LoadState>::incremental_compile_clause::hbb760f797a9d1334
  14:        0x1080dd038 - scryer_prolog::machine::compile::<impl scryer_prolog::machine::loader::Loader<TS>>::compile_clause_clauses::h5ad13622eaec9ac1
  15:        0x10804f466 - scryer_prolog::machine::loader::<impl scryer_prolog::machine::Machine>::compile_assert::h4c72d8054cc4a1e3
  16:        0x108054ddf - scryer_prolog::machine::Machine::handle_toplevel_command::hcbc4d2457d98f1d8
  17:        0x10805104f - scryer_prolog::machine::Machine::run_module_predicate::h665a482ee83b04f2
  18:        0x108051dd0 - scryer_prolog::machine::Machine::run_top_level::h98ad3e5a02b065d9
  19:        0x107f27f5e - scryer_prolog::main::hd9ecefa6a4ac075a
  20:        0x107f2c3ca - std::sys_common::backtrace::__rust_begin_short_backtrace::h1cd4f2d4668f330b
  21:        0x107f2c3ec - std::rt::lang_start::{{closure}}::hd97e1ceb299400ab
  22:        0x1083a70a0 - std::rt::lang_start_internal::hf4b96bfc8c02c8b0
  23:        0x107f280c9 - _main
✘-101
14:22 $```
pmoura commented 3 years ago

After fixing a bug in the hack for missing functionality in Scryer Prolog, re-running the tests shows:

% 510 test sets: 376 completed, 93 skipped, 25 broken, 9 timeouts, 7 crashes
% 7922 tests: 2496 skipped, 4872 passed, 554 failed

123 of the 554 failures are due to test goals succeeding non-deterministically when determinism is expected. The actual number of tests is also lower (~7100). There's a weird bug in Scryer where backtracking results in the same answer being repeated multiple times, which in turn results in tests being reported multiple times. For example:

?- {ack(loader)}.
% [ /Users/pmoura/logtalk/examples/ack/ack.lgt loaded ]
% [ /Users/pmoura/logtalk/examples/ack/loader.lgt loaded ]
% (0 warnings)
   true
;  ...
?- ack::ack(2, 4, V).
   V = 11
;  V = 11
;  V = 11
;  V = 11
;  V = 11
;  V = 11
;  V = 11
;  V = 11
;  V = 11.
?- 
pmoura commented 3 years ago

With 56bbcb1cb3b0d18b03177ade9e0e2d77f38ba7a3, we get running all tests in the Logtalk distribution:


$ logtalk_tester -p scryer -g "set_logtalk_flag(clean,off)" -w -t 360
...
% 510 test sets: 380 completed, 93 skipped, 23 broken, 5 timeouts, 9 crashes
% 5504 tests: 129 skipped, 5083 passed, 292 failed

Of those 292 test failures, 210 are for standards compliance tests. Experience tells that most failures are due to a relatively small number of bugs.

mthom commented 3 years ago

Still a ways to go, but that's great progress!