This is a stoics.infrastructure pack for
As of 0.3 the library also provides type errors on top of must_be/2
The main aim is to create contextual version of messages that can be used from different packs. In addition the library has evolved to provide some error related predicates.
Providing the context:
Argument errors (printing of Arg itself can be surpressed with prolog_flag(pack_errors_arg,false)
- useful for long data).
Poss is a list of positions and Args a list of arguments.
arg_enumerate(Pos,Vals,Arg)
see also type/3arg_ground(Pos,Arg)
,arg_ground_in_one_of(Poss,Args)
arg_ground_pattern(Poss,Args)
Other errors
cast(Term,From,To)
)lengths_mismatch(Tkn1,Tkn2,Len1,Len2)
lengths_mismatch(Tkn1,Tkn2,Op,Len1,Len2)
type_error(Type,Term)
type_error(Pos,Type,Term)
unknown_token(Tkn,Cat)
?- throw( pack_error(os,arg_ground(3,name(_))) ). ERROR: pack(os): Ground argument expected at position: 3 (found: name(_2064)) ?- set_prolog_flag(pack_errors_arg,false). ?- throw( pack_error(os,arg_ground(3,name(_))) ). ERROR: pack(os): Ground argument expected at position: 3 ?- set_prolog_flag(pack_errors_arg,true). ?- throw( pack_error(os,os_pred/3,arg_ground(3,name(_))) ). ERROR: os:os_pred/3: Ground argument expected at position: 3 (found: name(_2088)) ?- throw( pack_error(os,os_pred/3,arg_enumerate(3,[a,b,c],d)) ). ERROR: os:os_pred/3: Term at position: 3, is not one of: [a,b,c], (found: d) ?- throw( pack_error(mlu,lengths_mismatch(learners,predictions,3,4)) ). ERROR: pack(mlu): Lists for learners and predictions have mismatching lengths: 3 and 4 respectively ?- throw( pack_error(mlu,k_fold_learn/3,lengths_mismatch(learners,predictions,3,4)) ). ERROR: mlu:k_fold_learn/3: Lists for learners and predictions have mismatching lengths: 3 and 4 respectively ?- throw( pack_error(os,os_term/2,cast(abc('file.csv'),atom)) ). ERROR: os:os_term/2: Cannot cast: abc(file.csv), to type: atom
example file:
:- multifile( pack_errors:message/3 ). pack_errors:message( fold_data_insufficient(Dlen,N) ) --> ['Insufficient length of data (~d) as ~d folds are required'-[Dlen,N]]. pack_errors:message( fold_data_residual(Dlen) ) --> ['Residual data of length: ~d while splitting folds'-[Dlen]].
Once the above has been loaded, try with
?- throw( fold_data_insufficient(10,20) ). ERROR: Insufficient length of data (10) as 20 folds are required ?- throw( pack_error(mlu,fold_data_insufficient(10,20) ) ). ERROR: pack(mlu): Insufficient length of data (10) as 20 folds are required ?- throw( pack_error(mlu,k_fold_learn/4,fold_data_insufficient(10,20) ) ). ERROR: mlu:k_fold_learn/4: Insufficient length of data (10) as 20 folds are required
The library listens to debug(pack_errors)
.
Opts
report(Report=error)
ball(Ball)
instantiates the original exception Ball caught from calling Goal. (So that parts of it can be included in Error.)
?- caught( fail, my_exception(on_data), true ). ERROR: Unhandled exception: my_exception(on_data) ?- caught( fail, my_exception(on_data), [report(ignore)] ). true ?- caught( fail, my_exception(on_data), [report(fail)] ). false ?- caught( xyz, my_except(Ball), [ball(Ball)] ). ERROR: Unhandled exception: my_except(error(existence_error(procedure,pack_errors:xyz/0),context(system:catch/3,_11198)))
partial
and false
are collapsed to false
.
Groundness
==
?- ground( abc, Abc )
, ground( de(F), Def )
, ground( GHI, Ghi )
.
Abc = true,
Def = partial,
Ghi = false.
?- ground_binary( abc, Abc )
, ground_binary( de(F), Def )
, ground_binary( GHI, Ghi )
.
Abc = true,
Def = Ghi, Ghi = false.
OnThrow==succeed
Error is not thrown and the call itself succeeds.
For all other values the default behaviour is that of OnThrow==error
where is to thrown Error is assumed.
As of version 0.3 this should be the adviced entry point for throwing pack tracing balls.
Opts
on_throw(OnThrow=error)
one of [succeed,fail,error].
as_pack_err(Perr=true)
true wraps Error, as a pack_error
pack(Pack=_)
originator pack
pred(Pred=_)
originator predicate
pack_format(Pfmt=short)
output format for pack announcement
?- throw( my_error(x), true ). ERROR: Unhandled exception: my_error(x) ?- throw( my_error(x), on_throw(succeed) ). true. ?- throw( my_error(x), on_throw(fail) ). false. ?- throw( my_error(x), on_throw(error) ). ERROR: Unhandled exception: my_error(x) ?- throw( my_error(x), on_throw(whatelse) ). ERROR: Unhandled exception: my_error(x)
call(Callable)
), which will succeed iff
call( Callable, Term )
succeeds. It also enhances must_be/2 by adding options .
In the case of a call-wrapped type, the call to type/3 will succeed iff
call(Callable,Term)
succeeds.
Opts (unlisted is ok)
error(Err=true)
when false, call fails instead of throwing error
arg(Err=true)
some argument position of Term. (false is reserved and prints no info.)
pack(Pack=false)
when given, the error contains info on the pack throwing the error (false is reserved and prints no info)
pred(Pred=false)
when given, the error contains info on the predicate throwing the error (false is reserved and prints no info)
?- type( boolean, maybe ). ERROR: Object of type: boolean, expected but found term: maybe ?- type( boolean, maybe, error(false) ). false. ?- type( boolean, maybe, pack(sure) ). ERROR: pack(sure): Object of type: boolean, expected but found term: maybe ?- type( boolean, maybe, [pack(sure),pred(lost/2)] ). ERROR: sure:lost/2: Object of type: boolean, expected but found term: maybe ?- type( boolean, maybe, [pack(sure),pred(lost/2@3)] ). ERROR: Syntax error: Operator expected ERROR: type( boolean, maybe, [pack(sure),pred(lost/ ERROR: ** here ** ERROR: 2@3)] ) . ?- type( boolean, maybe, [pack(sure),pred(lost/2+3)] ). ERROR: sure:lost/2+3: Object of type: boolean, expected but found term: maybe ?- type( boolean, maybe, [pack(sure),pred(1+lost/2)] ). ERROR: sure:1+lost/2: Object of type: boolean, expected but found term: maybe ?- type( boolean, maybe, [pack(sure),pred(lost(arg1)/2)] ). ERROR: sure:lost(arg1)/2: Object of type: boolean, expected but found term: maybe
load(true)
)pack(lib)
's lib(suggests(Pack))
to, on-demand,
Note that pack(lib)
also provides
lib(suggests(Pid,Load))
which is an alternative and more automatic way to achieve demand driven loading via hot-swapping.
:- lib(suggests(Pack))
silently fails if Pack is not present. This is intendent for dependendencies that do not impact major parts for the importing pack. Thus allow common use without grabbing all dependencies that may not be needed for a particular user.
Opts are passed to throw/2, except for:
load(Load=false)
?- defined( abc/0, pack(b_real) ). ERROR: Predicate: abc/0 is not defined (source apparently available at: pack(b_real); not asked to load) ?- defined( abc/0, false ). ERROR: Predicate: abc/0 is not defined ?- defined( abc/0, false, pack(sourcey) ). ERROR: sourcey:$unknown/0: Predicate: abc/0 is not defined ?- defined( abc/0, pack(b_real), [pack(sourcey),pred(foo/1;2)] ). ERROR: sourcey:foo/1;2: Predicate: abc/0 is not defined (source apparently available at: pack(b_real); not asked to load) ?- defined( b_real/0, pack(b_real), [as_pack_err(true),load(library(b_real))] ). true.
The above only succeeds if b_real is an install library and defines b_real/0.
From or Load can have the special form: lib(CodeLib)
. This assumes pack(lib)
is installed and lib/1
will be used to load the requested CodeLib.
?- defined( b_real/0, lib(b_real), load(true) ),
Will again, only succeed if b_real is installed and defines b_real/0. In this occasion library(lib) should be also installed.
?- pack_errors_version( 0:3:0, date(2017,3,6) ).
The following predicates are exported, but not or incorrectly documented.