From: Mark Date: Wed, 4 Oct 2023 21:12:25 +0000 (-0600) Subject: use eager_stackful_preorder_iter in variable_set, add term_variables/1 tests X-Git-Tag: remove~49 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=0ad4427f83beb2f3bda59648a0a099ec75dd0e3b;p=scryer-prolog.git use eager_stackful_preorder_iter in variable_set, add term_variables/1 tests --- diff --git a/src/heap_iter.rs b/src/heap_iter.rs index d3b62527..bd583632 100644 --- a/src/heap_iter.rs +++ b/src/heap_iter.rs @@ -12,6 +12,14 @@ use modular_bitfield::prelude::*; use std::ops::Deref; use std::vec::Vec; +#[inline(always)] +pub fn eager_stackful_preorder_iter( + heap: &mut Heap, + value: HeapCellValue, +) -> EagerStackfulPreOrderHeapIter { + EagerStackfulPreOrderHeapIter::new(heap, value) +} + /* * Unlike StackfulPreOrderHeapIter, this iterator not only marks * cyclic terms for the sake of skipping them at the second visit but diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 4510fa5d..4ed05354 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -1621,7 +1621,7 @@ impl MachineState { // returns true on failure. pub fn ground_test(&mut self) -> bool { - let iter = EagerStackfulPreOrderHeapIter::new(&mut self.heap, self.registers[1]); + let iter = eager_stackful_preorder_iter(&mut self.heap, self.registers[1]); for term in iter { if term.is_var() { diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 40881c54..ba211683 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -583,20 +583,11 @@ impl MachineState { seen_set: &mut IndexSet, value: HeapCellValue, ) { - let mut iter = stackful_preorder_iter::(&mut self.heap, &mut self.stack, value); + let iter = eager_stackful_preorder_iter(&mut self.heap, value); - while let Some(value) = iter.next() { - let value = unmark_cell_bits!(value); - - if value.is_var() { - let value = unmark_cell_bits!(heap_bound_store( - iter.heap, - heap_bound_deref(iter.heap, value) - )); - - if value.is_var() { - seen_set.insert(value); - } + for term in iter { + if term.is_var() { + seen_set.insert(term); } } } diff --git a/src/tests/term_variables.pl b/src/tests/term_variables.pl new file mode 100644 index 00000000..57c55ed1 --- /dev/null +++ b/src/tests/term_variables.pl @@ -0,0 +1,84 @@ +/**/ + +:- use_module(library(format)). +:- use_module(library(dcgs)). +:- use_module(library(lists)). +:- use_module(library(debug)). + +test("term_variables#1400", ( + term_variables(A+B*C/B-D, Vars), + term_variables(t(A,B,C,D), Vars), + Vars = [A,B,C,D] +)). + +test("term_variables#1405", ( + \+ (B=[C|D],C=[_|D],C=[B|B], term_variables(B,_), false) +)). + +test("term_variables#1409", ( + G_0 = (A=[B|B],A=[C|C]), G_0, term_variables(G_0, Vars), Vars = [B] +)). + +test("term_variables#1410", ( + \+ \+ (G_0 = ( A=s(A) ), G_0, term_variables(G_0, Vars), Vars = []), + E_0 = (_=[B|B]), G_0 = (E_0,\_=B), G_0, term_variables(G_0, Vars) +)). + +test("term_variables#1412", ( + G_0 = =([A|B],[A|B]), G_0, term_variables(G_0, Vars), + Vars = [A,B] +)). + +test("term_variables#1414", ( + \+ (\B=A,C=[A|D],B=[a,b|E],C=[D|E], term_variables(\E,_), false) +)). + +test("term_variables#2063", ( + A=[B|C], B=[A], term_variables([B], Vars), + Vars = [C] +)). + +main :- + findall(test(Name, Goal), test(Name, Goal), Tests), + run_tests(Tests, Failed), + show_failed(Failed), + halt. + +main_quiet :- + findall(test(Name, Goal), test(Name, Goal), Tests), + run_tests_quiet(Tests, Failed), + ( Failed = [] -> + format("All tests passed", []) + ; format("Some tests failed", []) + ), + halt. + +run_tests([], []). +run_tests([test(Name, Goal)|Tests], Failed) :- + format("Running test \"~s\"~n", [Name]), + ( call(Goal) -> + Failed = Failed1 + ; format("Failed test \"~s\"~n", [Name]), + Failed = [Name|Failed1] + ), + run_tests(Tests, Failed1). + +run_tests_quiet([], []). +run_tests_quiet([test(Name, Goal)|Tests], Failed) :- + ( call(Goal) -> + Failed = Failed1 + ; Failed = [Name|Failed1] + ), + run_tests_quiet(Tests, Failed1). + +portray_failed_([]) --> []. +portray_failed_([F|Fs]) --> + "\"", F, "\"", "\n", portray_failed_(Fs). + +portray_failed([]) --> []. +portray_failed([F|Fs]) --> + "\n", "Failed tests:", "\n", portray_failed_([F|Fs]). + +show_failed(Failed) :- + phrase(portray_failed(Failed), F), + format("~s", [F]). diff --git a/tests/scryer/src_tests.rs b/tests/scryer/src_tests.rs index 8a04abbe..edc43d32 100644 --- a/tests/scryer/src_tests.rs +++ b/tests/scryer/src_tests.rs @@ -93,3 +93,12 @@ fn ground_tests() { "All tests passed", ); } + +#[test] +fn term_variables_tests() { + run_top_level_test_with_args( + &["src/tests/term_variables.pl", "-f", "-g", "main_quiet"], + "", + "All tests passed", + ); +}