Installation using SWI-Prolog 8.1.x or later (due to duplicate transitive deps failing in earlier versions):
`?- pack_install('https://github.com/logicmoo/logicmoo_utils.git'). `
Example usages:
% Wrap `quietly/1` over parts of your code you no longer need to stepped thru.
% This is a *nondeterministic* version of notrace/1 ! (Instead of like once/1)
quietly(Goal):-
tracing ->
each_call_cleanup(notrace,Goal,trace);
Goal.
% Scope *when* a prolog flag is set
with_prolog_flag(Flag,Value,Goal):-
current_prolog_flag(Flag,Was),
each_call_cleanup(
set_prolog_flag(Flag,Value),
Goal,
set_prolog_flag(Flag,Was)).
% Trace non interactively *sometimes*
rtrace(Goal):-
( tracing-> Undo=trace ; Undo = notrace ),
'$leash'(OldL, OldL), '$visible'(OldV, OldV),
each_call_cleanup(
(notrace,visible(+all),leash(-all),leash(+exception),trace),
Goal,
(notrace,'$leash'(_, OldL),'$visible'(_, OldV),Undo)).
?- use_module(library(logicmoo_utils)).
true.
?- rtrace(member(X,[1,2,3])).
Call: (9) lists:member(_8730, [1, 2, 3])
Unify: (9) lists:member(_8730, [1, 2, 3])
Exit: (9) lists:member(1, [1, 2, 3])
X = 1 ;
Redo: (9) lists:member(_8730, [1, 2, 3])
Exit: (9) lists:member(2, [1, 2, 3])
X = 2 ;
Redo: (9) lists:member(_8730, [1, 2, 3])
Exit: (9) lists:member(3, [1, 2, 3])
X = 3.
?- rtrace(member(X,[1,2,3])),member(Y,[4,5]).
Call: (10) lists:member(_10508, [1, 2, 3])
Unify: (10) lists:member(_10508, [1, 2, 3])
Exit: (10) lists:member(1, [1, 2, 3])
X = 1,
Y = 4 ;
X = 1,
Y = 5 ;
Redo: (10) lists:member(_10508, [1, 2, 3])
Exit: (10) lists:member(2, [1, 2, 3])
X = 2,
Y = 4 ;
X = 2,
Y = 5 ;
Redo: (10) lists:member(_10508, [1, 2, 3])
Exit: (10) lists:member(3, [1, 2, 3])
X = 3,
Y = 4 ;
X = 3,
Y = 5.
?- rtrace((member(X,[1,2,3]),member(Y,[4,5]))).
Call: (10) lists:member(_11854, [1, 2, 3])
Unify: (10) lists:member(_11854, [1, 2, 3])
Exit: (10) lists:member(1, [1, 2, 3])
Call: (10) lists:member(_11872, [4, 5])
Unify: (10) lists:member(_11872, [4, 5])
Exit: (10) lists:member(4, [4, 5])
X = 1,
Y = 4 ;
Redo: (10) lists:member(_11872, [4, 5])
Exit: (10) lists:member(5, [4, 5])
X = 1,
Y = 5 ;
Redo: (10) lists:member(_11854, [1, 2, 3])
Exit: (10) lists:member(2, [1, 2, 3])
Call: (10) lists:member(_11872, [4, 5])
Unify: (10) lists:member(_11872, [4, 5])
Exit: (10) lists:member(4, [4, 5])
X = 2,
Y = 4 ;
Redo: (10) lists:member(_11872, [4, 5])
Exit: (10) lists:member(5, [4, 5])
X = 2,
Y = 5 ;
Redo: (10) lists:member(_11854, [1, 2, 3])
Exit: (10) lists:member(3, [1, 2, 3])
Call: (10) lists:member(_11872, [4, 5])
Unify: (10) lists:member(_11872, [4, 5])
Exit: (10) lists:member(4, [4, 5])
X = 3,
Y = 4 ;
Redo: (10) lists:member(_11872, [4, 5])
Exit: (10) lists:member(5, [4, 5])
X = 3,
Y = 5.
This is a miniture part of a very large debugging library... Some better parts of that library are not yet added.
Here are current uses:
?- use_module(library(logicmoo_utils)).
Wrap must/1
over parts of your code you do not trust yet.
If your code fails.. it will rewind to your entry block (at the scope of this declaration) and invoke rtrace/1 .
If there are 50 steps to your code, it will save you from pushing creep
50 times.
Instead it turns off the leash to allow you to trace with your eyeballs instead of your fingers
:- must(member(3,[4,5])).
..... TODO Doc this .....
Wrap `sanity/1` over parts of your code you want to turn on/off that is only usefull for slow debugging
```prolog
:- sanity(sleep(10)).
..... TODO Doc this .....
Wrap nop/1
over parts of your code you do not want to quickly comment out yet not break syntax.
Defined as:
:- meta_predicate nop(0).
nop(_).
..... TODO Doc this .....
New ways to avoid duplicate solutions
?- use_module(library(logicmoo_utils)).
?- no_repeats( X , member(X-Y,[3-2,1-4,1-5,2-1])).
% X = 3, Y = 2 ;
% X = 1, Y = 4 ;
% X = 2, Y = 1.
?- no_repeats(member(X,[3,1,1,1,3,2])).
% X = 3 ;
% X = 1 ;
% X = 2.
New simple loop checking
Allows code to declare special locations that loop prevention will occur
?- use_module(library(logicmoo_utils)).
true.
?- TODO Doc this
:- use_module(library(file_scope)).
:- set_prolog_flag_until_eof(access_level, system).
:- assert_until_eof(( term_expansion(.,.) :- .. )).
Hook and/or override assert, retract, call, clause, erase, etc for specific predicates
?- use_module(library(hook_database)).
true.
?- TODO Doc this
An alternate interface to the clause database to allow attributed variables to be asserted/read
?- use_module(library(hook_database)).
true.
?- TODO Doc this
?- use_module(library(hook_database)).
true.
?- TODO Doc this
Call a Goal with local assertions
locally_each( :Effect, :Call) is nondet.
Temporally have :Effect (see locally/2)
But Ensure Non-determism is respected (effect is undone between each Redo)
uses each_call_cleanup/3 instead of setup_call_cleanup/3 (slightly slower?)
for example,
locally_each/2 works (Does not throw)
?- current_prolog_flag(xref,Was),
locally_each(set_prolog_flag(xref,true),
assertion(current_prolog_flag(xref,true));assertion(current_prolog_flag(xref,true))),
assertion(current_prolog_flag(xref,Was)),fail.
locally/2 is little less carefull so it should not work (it throws instead)
?- current_prolog_flag(xref,Was),
locally(set_prolog_flag(xref,true),
assertion(current_prolog_flag(xref,true));assertion(current_prolog_flag(xref,true))),
assertion(current_prolog_flag(xref,Was)),fail.
locally( :Effect, :Call) is nondet.
Effect may be of type:
set_prolog_flag - Temporarily change prolog flag
op/3 - change op
$gvar=Value - set a global variable
Temporally (thread_local) Assert some :Effect
use locally_each/3 if respecting Non-determism is important (slightly slower?)
?- current_prolog_flag(xref,Was),
locally(set_prolog_flag(xref,true),
assertion(current_prolog_flag(xref,true))),
assertion(current_prolog_flag(xref,Was)).
:- set_prolog_flag_until_eof(access_level,system).
:- assert_until_eof(( term_expansion(.,.) :- .. )).
# Utilities to open various objects for read/write
```prolog
?- use_module(library(logicmoo_utils)).
?- use_module(library(logicmoo_utils)).
( Please ask to be added to logicmoo and Contribute directly ! )
I really dislike having tons of forks that are several commits behind the main git repo.
Rather just give you commit access (feel free to work from a branch)
Still, we wont stop you from doing it the Fork+PullRequest method
Copyright (c) 1997 - 2018 logicmoo and Douglas Miles [email protected]
Document this pack!
Write tests
./must_sanity.pl
./hook_database.pl
./file_scope.pl
./logicmoo_startup.pl
./logicmoo_common.pl
./no_repeats/no_repeats.pl
./loop_check/no_loops.pl
./scope_locally/with_no_x.pl
./scope_locally/with_thread_local.pl
./scope_locally/each_call_cleanup.pl
./expand_finer/subclause_expansion.pl
./file_utils/script_files.pl
./xlisting/xlisting_web/logicmoo_run_clio.pl
./xlisting/xlisting_web/mpred_rdf.pl
./xlisting/xlisting_web/logicmoo_run_pldoc.pl
./xlisting/xlisting_web/mpred_pldoc_util.pl
./xlisting/xlisting_web/xlisting_web.pl
./xlisting/xlisting_web/xlisting_web.pfc.pl
./xlisting/xlisting_web/swish_lib/render/html.pl
./xlisting/xlisting_web/xlisting_web_sanity_tests.pl
./xlisting/xlisting_web/logicmoo_run_swish.pl
./xlisting/listing_vars.pl
./xlisting/xlisting.pl
./debuggery/bugger.pl
./debuggery/block3.pl
./debuggery/frames.pl
./debuggery/dumpst.pl
./debuggery/rtrace.pl
./debuggery/unused_rtrace.pl
./debuggery/ucatch.pl
./debuggery/first.pl
./debuggery/util_supp.pl
./debuggery/dmsg.pl
./debuggery/sanity_tests.pl
./hybrid_db/attvar_serializer.pl
./hybrid_db/toplevel_variable_names.pl
./hybrid_db/call_from_module.pl
./hybrid_db/sanity_tests_cav.pl
./hybrid_db/predicate_inheritance.pl
./hybrid_db/retry_undefined.pl
./hybrid_db/virtualize_source.pl
./hybrid_db/lockable_vars.pl
./hybrid_db/clause_attvars.pl
./hybrid_db/sanity_tests.pl
./hybrid_db/attvar_reader.pl
./misc_lm/logicmoo_util_bb_env.pl
./misc_lm/logicmoo_util_bb_gvar.pl
./misc_lm/logicmoo_util_dra.pl
./misc_lm/logicmoo_util_ctx_frame.pl
./misc_lm/logicmoo_util_structs.pl
./misc_lm/logicmoo_util_butterfly.pl
./misc_lm/logicmoo_util_dlist.pl
./misc_lm/logicmoo_util_strings.pl
./misc_lm/logicmoo_util_engines.pl
./misc_lm/logicmoo_util_terms.pl
./file_utils/filestreams.pl
./file_utils/filesystem.pl