Should you find a bug in XSB, please report it using our bug tracking system at http://sourceforge.net/bugs/?group_id=1176 and also to xsb-development@lists.sourceforge.net
svn checkout svn://svn.code.sf.net/p/xsb/src/trunk xsb-src
| ?- catch((T=a,X is _),error(E,_),true). T = a X = _h207 E = type_error(evaluable,_h405);Expected:
E = instantiation_error
and T = _h1232
| ?- catch((Xs=[a|Xs],X is _),error(E,_),true), var(Xs). noExpected: Succeeds with
E = instantiation_error
[ valid_type = evaluable, culprit = _164, goal = ... ](See more about it in the manuals, specifically Chapter 8 Contexts, exception/2, context/2)
This term is normally not copied upon error. But first, a
fitting catcher is searched. If it is catch/3
, only then the
error-term is copied.
But if the catcher is exception_handler/3
, the replacing
goal is executed in the very place of the built-in that produced the error.
[user] ?- exception_handler(X > Y, error(instantiation_error, P), writeq((X>Y->P))). _164 > _165 -> _309 :: [_278 :: (valid_type = evaluable) |_287 :: [ culprit = _164, goal = system : exception_handler(_164 > _165, error(instantiation_error,_309), writeq((_164 > _165 -> _309))) @ user]]or simplified:
_164 > _165 -> _309 :: [ valid_type = evaluable, culprit = _164, goal = system : exception_handler(_164 > _165, error(instantiation_error,_309), writeq((_164 > _165 -> _309))) @ user]Note the sharing of
_309
which makes this an infinite
term. Also note that the original goal and the corresponding
variables (_164
and _165
) are all
shared. When using catch, the term is copied:
[user] ?- catch(X > Y, error(instantiation_error, P), writeq((X>Y->P))). _164 > _165 -> [ valid_type = evaluable, culprit = _273, goal = system : catch(_273 > _291,error(instantiation_error,_294),writeq((_273 > _291 -> _294))) @ user]In this manner it is also possible to convey the information whether or not a prticular built-in can be "restarted". It might not be possible to restart it at all, since trailing information is no longer present etc.
IF's way to print infinite terms: Only infinite termins are printed using ::.
[user] ?- current_op(50,xfx,::). [user] ?- X = s(X), writeq(X),nl,fail. _165 :: s(_165) [user] ?- blam(L), X = s(L,X). ... L = [[[[]],[]],[[]],[]] X = _168 :: s([_228 :: [_230 :: [[]]|_230]|_228],_168) ; L = [[[[[]],[]],[[]],[]],[[[]],[]],[[]],[]] X = _168 :: s([_228 :: [_230 :: [_232 :: [[]]|_232]|_230]|_228],_168)
| ?- X is 1/0, Y is X* -1, write_canonical(f(X,Y)). f(inf.0,-inf.0) | ?- X is inf.0. ++Error[XSB/Runtime/P]: [Syntax] () X is inf <--- HERE? ************The text
inf.0
are 3 valid tokens [inf,.,0]
that could form valid Prolog syntax by adding appropriate
operators. That is, either infix .
or
prefix inf
and prefix dot. So far, every systems makes
its own incompatible extension.
Ideally, there is full support of the base model offered in
ISO and appropriate extensions.
| ?- write_canonical(10.0e100). 9.9999999999999998e+100 yes | ?- writeq(10.0e100). 99999999999999997704951326524533662844684271992415000612999597473199345218078991130326129448151154688.0000 yes
| ?- writeq(f(:-)+[:-]). f((:-)) + [(:-)] yes | ?- writeq(:-). (:-) yesexpected: no brackets around
:-
.
There is never a reason to put round brackets around an atom that is an argument in functional notation, an element or rest of a list, or at the top. In fact, some 10+ cases could be removed by avoiding extra brackets.
| ?- X is 2^ -1. X = 0; noExpected:
type_error(float,2)
.
| ?- number_chars(1,[[]|_]). noExpected: type_error(character,[])
| ?- X = s(X), subsumes_term(X,s(X)).This cannot be interrupted. It would make sense to make this succeed. After all it holds that, X = s(X), X == s(X).
| ?- X = s(X), unify_with_occurs_check(X,Y). C-c C-c[ Break (level 1) ]While this is perfect w.r.t. the standard ; there, this case is undefined, it would help much more to make this case succeed.
While compiling XSB/lib: ++Warning[XSB]: [Compiler] format : Unused symbol C/3
| ?- catch(_=..[1|_],Pat,true). Pat = error(type_error(atomic,1),in arg 2 of predicate =../2,[]);Expected: instantiation_error.
A type error is never correct here, because _=..[1]
is an
instance of above goal and does succeed.
| ?- X is 1/3,writeq(X). 0.3333 X = 0.3333 yes | ?- X is 1/3,write_canonical(X). 0.333333333333333 X = 0.3333 yesExpected: Same result as write_canonical/1.
uninstantiation_error
,
op/3
errorsterm_variables/2
errorscompare/3
errors,
sort/2
errors,
keysort/2
errors.
| ?- is_acyclic(X). X = _h164 yes | ?- is_cyclic(X). no
| ?- X = f(_h192,_). X = f(_h178,_h192)
| ?- catch(number_chars(1,[' ',[]]),error(E,_,_),true), writeq(E). type_error('digit atom',[' ',[]])Expected:
type_error(character,[])
. So there are two
differnces (apart from error/3): the type should be character. And
the culprit should be [].
ulrich@gupu2:~/iso-prolog$ /opt/gupu/xsb-cvs/3.3.5/bin/xsb [xsb_configuration] [sysinitrc] XSB Version 3.3.1 (Pignoletto) of April 12, 2011 [i686-pc-linux-gnu; mode: optimal; engine: slg-wam; scheduling: local; word size: 32] [build date: Sat Apr 30 00:51:30 CEST 2011] | ?- X is xor(2,3). X = 1
| ?- catch((length(K,L),fail),Pat,true). UNRECOVERABLE ERROR: Ran our of tagged address space! Exiting XSB abnormally...
ulrich@gupu2:~/iso-prolog$ /opt/gupu/xsb-cvs/3.2/bin/xsb [xsb_configuration loaded] [sysinitrc loaded] XSB Version 3.2 (Kopi Lewak) of March 15, 2009 [i686-pc-linux-gnu; mode: optimal; engine: slg-wam; scheduling: local; word size: 32] | ?- use_module(basics,length/2). yes | ?- length(Xs,2). Xs = [_h203,_h205] yes | ?- call(length(Xs),2). Xs = [_h219,_h221] yes | ?- use_module(inex,length/1). yes | ?- length(Xs,2). Xs = [_h203,_h205] yes | ?- call(length(Xs),2). ++Error[XSB/Runtime/P]: [Existence (No module inex exists)] in arg 1 of predicate load Forward Continuation... ... machine:xsb_backtrace/1 ... loader:load/1 ... loader:load_pred1/1 ... loader:load_pred0/1 ... loader:load_pred/1 ... x_interp:_$call/1 ... x_interp:call_query/1 ... standard:call_expose/1 ... standard:catch/3 ... x_interp:interpreter/0 ... loader:ll_code_call/3 ... standard:call_expose/1 ... standard:catch/3
| ?- X = '1'. X = 1Expected X = '1'. writeq/1.
| ?- catch(X is-1**1.5,error(E,_),true). X = nan E = _h175;Expected:
E = evaluation_error(undefined)
| ?- Xs=[a|Xs],atom_chars(A,Xs). Partial Forward Continuation... ... _$call/1 ... call_query/1 ... call_c/1 ... call_expose/1 ... catch/3 ... interpreter/0 ... ll_code_call/3 ... call_expose/1 ... catch/3 ++Memory violation occurred during evaluation. ++Please report this problem using the XSB bug tracking system accessible from ++ http://sourceforge.net/projects/xsb ++Please supply the steps necessary to reproduce the bug. Exiting XSB abnormally...Expected:
type_error(list,[a| ...])
g3:/opt/gupu/src/XSB/build> /opt/gupu/XSB/3.2/bin/xsb [xsb_configuration loaded] [sysinitrc loaded] XSB Version 3.2 (Kopi Lewak) of March 15, 2009 [x86_64-unknown-linux-gnu; mode: optimal; engine: slg-wam; scheduling: local; word size: 64] | ?- call_cleanup((X=1;X=2),(write(cleanup(X,Y)),nl)),Y=bound,!,throw(x). cleanup(1,bound)Now:Partial Forward Continuation... Local Stack clobbered, no backtrace available (h:0x2aaaab31cdb0,e:0x2aaaab31cde0) ++Memory violation occurred during evaluation. ++Please report this problem using the XSB bug tracking system accessible from ++ http://sourceforge.net/projects/xsb ++Please supply the steps necessary to reproduce the bug. Exiting XSB abnormally...
| ?- call_cleanup((X=1;X=2),(write(cleanup(X,Y)),nl)),Y=bound,!,throw(x). cleanup(1,bound) ++Error[XSB]: [Runtime/C] no heap space in xsb_throw_internal ++Error[XSB]: [Runtime/C] Exiting XSB abnormally...
setup_call_cleanup(Setup, Call, Cleanup) :- once(Setup), call_cleanup(Call, Cleanup).The difference to call_cleanup/2 is that setup_call_cleanup/3 is able to provide provisions for handling interrupts/timeouts and other asynchronous signals during Setup in a more robust fashion. Consider:
file_term(File, Term) :- setup_call_cleanup( open(File, read, Stream), ( repeat, read(Stream, Term), ( Term == end_of_file -> ! ; true ) ), close(Stream)).The idea is to read the file term-by-term. At the end, or when the caller is satisfied, the stream is closed. But what happens, if there is an interrupt immediately after the goal open/3? The cleanup handler might not be installed at that very moment - and the Stream is never closed thereby using system resources.
Most uses of call_cleanup/2 are better handled by setup_call_cleanup/3. In many applications it is not a big problem, if something leaves some files open in case of errors, but in some like servers it is a big problem.
| ?- call_cleanup(throw(goal_exception),throw(cleanup_exception)). ++Error[XSB/Runtime] Unhandled Exception: cleanup_exceptionExpected:
| ?- call_cleanup(throw(goal_exception),throw(cleanup_exception)). ++Error[XSB/Runtime] Unhandled Exception: goal_exception
g3:/opt/gupu/src/XSB/build> /opt/gupu/XSB/3.2/bin/xsb [xsb_configuration loaded] [sysinitrc loaded] XSB Version 3.2 (Kopi Lewak) of March 15, 2009 [x86_64-unknown-linux-gnu; mode: optimal; engine: slg-wam; scheduling: local; word size: 64] | ?- call_cleanup((X=1;X=2),(write(cleanup(X,Y)),nl)),Y=bound,throw(x). ++Error[XSB/Runtime] Unhandled Exception: xExpected:
| ?- call_cleanup((X=1;X=2),(write(cleanup(X,Y)),nl)),Y=bound,throw(x). cleanup(_h124,_h222) ++Error[XSB/Runtime] Unhandled Exception: x | ?-