CHR in SWI Prolog: Rule guard containing "just removed" constraint does not return, blows stack - prolog

A little test code with no particular meaning:
:- use_module(library(chr)).
:- chr_constraint foo/1, bar/1, anyone/2.
foo(X) \ bar(Y) <=> anyone(X,Y).
anyone(_,Y) <=> bar(Y) | writef("bar(%w) exists\n",[Y]).
anyone(_,Y) <=> writef("bar(%w) does not exist\n",[Y]).
If the above is consulted from the SWI Prolog command line and then run with:
?- foo(8),bar(10).
there is overflow after some time:
Could not reenable global-stack
Could not reenable global-stack
ERROR: Out of global-stack.
ERROR: No room for exception term. Aborting.
Could not reenable global-stack
ERROR: Out of global-stack.
ERROR: No room for exception term. Aborting.
ERROR: Execution Aborted
% Execution Aborted
However, if the code for the second rule is changed by moving the test for bar from the guard ot the head:
:- use_module(library(chr)).
:- chr_constraint foo/1, bar/1, anyone/2.
foo(X) \ bar(Y) <=> anyone(X,Y).
anyone(_,Y),bar(Y) <=> writef("bar(%w) exists\n",[Y]). % changed!
anyone(_,Y) <=> writef("bar(%w) does not exist\n",[Y]).
then execution terminates:
?- foo(8),bar(10).
bar(10) does not exist
foo(8).
Is this an accident of the implementation? It does seem a bit dicey.
Furthermore, the above code was written because I wanted to test whether the constraint to be removed from the store (here, bar(Y)) would be available in the body of the rule. Apparently not, it is already gone when the rule body executes; but is this implementation dependent or a necessary or specified behaviour of CHR?

Related

Expert system returns this "catch/1" error

Below in code, the representation of a expert system to give response to a pattern of problems in a device (in this case, a mobile one), with the result being the probable cause of the issues, but as you may have seen in the title, this throw a especific error:
go :- catch(Problem),
print("Your problem is probably a"),
print(Problem),
print("Issue"),
nl.
input(Question) :-
write('You have problems such as the follwing:'),
write(Question),
write('?'),
read(output),
nl,
(( output == yes; output == y)
->
assert(yes(Question));
assert(no(Question)), fail).
:- dynamic yes/3, no/1.
verify(Problem):-
(yes(Problem)
-> true;
(no(Problem)
->
fail;
input(Problem))).
undo :- retract(yes(_)),fail.
undo :- retract(no(_)),fail.
undo.
grasp(low_battery) :- low_battery,!.
grasp(software_problem) :- software_problem,!.
grasp(hardware_problem) :- low_battery,!.
%grasp(virus_or_memory_issue) :- virus_or_memory_issue,!.
low_battery :-
verify(phone_not_recharged),
verify(charger_not_working).
software_problem :-
verify(device_turns_on_but_crashes),
verify(some_program_dont_work),
verify(more_than_one_program_crashes_after_awhile),
verify(some_programs_are_not_updated_or_deprecated).
%hardware_problem :-
%verify(device_dont_turn_on),
%verify(device_warmth_frequently),
%verify(screen_exhibits_atipical_visual_patters),
%verify(problems_began_or_intensified_after_fall_or_any_damage).
As a result, the given console is as follows:
ERROR: Unknown procedure: catch/1
ERROR: However, there are definitions for:
ERROR: catch/3
ERROR:
ERROR: In:
ERROR: [11] catch(_4812)
ERROR: [10] go at c:/users/victo/onedrive/documentos/prolog/sistema_especialista.pl:1
ERROR: [9] toplevel_call(user:user:go) at c:/program files/swipl/boot/toplevel.pl:1158
Exception: (11) [user] catch(_4356) ?
Searching for material I've found very little on such matter, and other algoritms I've found were quite not like this one. Any help would be very welcome.

How to repair error in Einstein Zebra in prolog >

I have a problem with zebra puzzle.
rightOf(A,B,(B,A,_,_,_)).
rightOf(A,B,(_,B,A,_,_)).
rightOf(A,B,(_,_,B,A,_)).
rightOf(A,B,(_,_,_,B,A)).
middleHouse(A,(_,_,A,_,_)).
firstHouse(A,(A,_,_,_,_)).
nextTo(A,B,(A,B,_,_,_)).
nextTo(A,B,(_,A,B,_,_)).
nextTo(A,B,(_,_,A,B,_)).
nextTo(A,B,(_,_,_,A,B)).
nextTo(A,B,(B,A,_,_,_)).
nextTo(A,B,(_,B,A,_,_)).
nextTo(A,B,(_,_,B,A,_)).
nextTo(A,B,(_,_,_,B,A)).
house[Nationality,Pet,Sport,Drinks,Colour].
zebra_owner(Owner) :-
houses(Houses),
exists(house(Owner,zebra,_,_,_), Houses).
length(5,Houses),
exists(house(british,_,_,_,red),Houses),
exists(house(spanish,dog,_,_,_),Houses),
exists(house(_,_,_,coffe,green),Houses),
exists(house(ukrainian,_,_,tea,_),Houses),
rightOf(house(_,_,_,_,green),house(_,_,_,_,ivory),Houses),
exists(house(_,snail,tennis,_,_),Houses),
exists(house(_,_,chess,_,yellow),Houses),
middleHouse(house(_,_,_,mlik,_),Houses),
firstHouse(house(norwegian,_,_,_,_),Houses),
nextTo(house(_,_,rugby,_,_),house(_,fox,_,_,_),Houses),
nextTo(house(_,_,chess,_,_),house(_,horse,_,_,_),Houses),
exists(house(_,_,volleyball,orangejuice,_),Houses),
exists(house(japanese,_,_,_,_),Houses),
nextTo(house(norwegian,_,_,_,_),house(_,_,_,_,blue),Houses),
nextTo(house(_,_,_,tea,_),house(_,_,_,milo,_),Houses),
exists(house(zebra_owner,zebra,_,_,_),Houses).
Under
house[Nationality,Pet,Smokes,Drinks,Colour].
I see the error: Singleton variables: house[Nationality,Pet,Smokes,Drinks,Colour].
And when I write ?- zebra_owner(Owner)
I see the error: procedure 'houses(A)' does not exist. Reachable from:zebra_owner(A).`
You cannot write
house[Nationality,Pet,Sport,Drinks,Colour].
that's non-existent syntax.
To express that predicate house/1 is valid for list [Nationality,Pet,Sport,Drinks,Colour], write:
house([Nationality,Pet,Sport,Drinks,Colour]).
You also must pay attention to predicate naming: houses/1 is not house/1. Predicate houses/1 is defined nowhere (the error message is wrong, it should really say predicate houses/1 is undeclared).

I am not sure as to why 'find_identity(X)' is returning as false [Code Below]

Snippets of my code are shown below. After doing a lot of cumbersome tracing, I have reached a point where I think it's the external modules which are the source of my problem, as the findall in links_of_actor never gets called, but links_of_actor itself gets called. I would be very grateful to anyone who can help and can clarify/add more of my code to this question if needed.
find_identity(A) :-
all_actor_links(ALs),
find_identity(ALs,[],A).
find_identity([a(A,_)],_,A).
find_identity(ALs,Ms,A) :-
agent_ask_oracle(oscar,o(1),link,L),
( memberchk(L,Ms) -> find_identity(ALs,Ms,A)
; otherwise -> purge_actors(ALs,L,NewALs),
find_identity(NewALs,[L|Ms],A)
).
links_of_actor(A,Ls) :-
actor(A),
wp(A,WT),
findall(L,wt_link(WT,L),Ls1),
findall(L,link(L),Ls2),
intersection(Ls1,Ls2,Ls).
actor_links(A,a(A,Ls)) :-
links_of_actor(A,Ls).
all_actor_links(ALs) :-
findall(A,actor(A),As),
maplist(actor_links,As,ALs).
----------------------------------------------------- Support Functions ---------------------------------------------------
% wp(Q,WT) <- issue query Q to Wikipedia and return the page in wikitext format
wp(Q,WT):-
wp_cache(Q,WT),!.
wp(Q,WT):-
wp_query2URL(Q,URL),
http_get(URL,R,[]),
atom_json_term(R,RR,[]),
wt_get(RR,WT0),
( atomic_list_concat1(_L,'#REDIRECT',WT0) -> wt_link(WT0,QQ),wp(QQ,WT)
; otherwise -> WT=WT0
),
assert(wp_cache(Q,WT)).
------------------------------------------------------------ Edit ----------------------------------------------------------------
After using the guitracer that is available with prolog, I have found that the program fails at http_get(URL,R,[]) in the wp(Q,WT) predicate. However, I am still not sure as to why this isn't working - Could it be possibly because of my internet?
To clarify, the predicate actor is defined in my file: actor('Billy Bob Thornton'). etc. and so are the links : link('Barack Obama')..
Using these definitions, the error can be localized by adding a # in front of those goals that have to succeed.
...
wp(Q,WT):-
#wp_query2URL(Q,URL),
#http_get(URL,R,[]),
#atom_json_term(R,RR,[]),
#wt_get(RR,WT0),
...
Well, did you try to see if the URL you gave to http_open is actually valid? You can always test from the top-level if you can http_open an URL:
?- use_module(library(http/http_client)).
true.
?- http_open("stackoverflow.com", R, []).
R = % a lot of stuff

source_sink error in prolog using rdf_load

I want to load rdf url from this rule:
getActorFilms(Actor_Name,Films):-
my_replace(Actor_Name, ' ', '_', Correct_Syntax_Of_Actor_Name),
string_concat('http://dbpedia.org/data/',Correct_Syntax_Of_Actor_Name, URL_TO_LOAD),
string_concat(URL_TO_LOAD,'.rdf',RDF_URL),
rdf_load(RDF_URL),
rdf(Films, 'http://dbpedia.org/ontology/starring', Object)
.
when the input is e.g. for an example 'Hugh Jackman'
it tells the error:
ERROR: [Thread pdt_console_client_0_Default Process] source_sink `http://dbpedia.org/data/Hugh_Jackman.rdf' does not exist
I'm really concerned about the ` character between http and source_sink
I think it should be '
although the url is correct, so what to do with that error?
You should pass an atom to rdf_load, not a string. This behavior (the misleading error message, not accepting a string) is probably a bug.
This works for me:
?- use_module(library('semweb/rdf_db')).
true.
?- use_module(library('semweb/rdf_http_plugin')).
true.
?- rdf_load('http://dbpedia.org/data/Hugh_Jackman.rdf').
% Parsed "http://dbpedia.org/data/Hugh_Jackman.rdf" in 0.02 sec; 371 triples
true.
?- string_to_atom(S, 'http://dbpedia.org/data/Hugh_Jackman.rdf'), rdf_load(S).
ERROR: source_sink `http://dbpedia.org/data/Hugh_Jackman.rdf' does not exist
I hope this solves your problem.

Raise an error in SWI Prolog

I'd like to print a message and stop the evaluation of the predicate. How do I do that?
Take a look at this link where the catch/3 and throw/1 mechanisms in Prolog are described.
It is possible to throw an exception or handle an exception using this mechanism.
The example (given on the site) is:
p:- true.
p:- throw(b).
q:- catch(p, B, write('hellop')), r(c).
r(X) :- throw(X).
Then the call:
?- catch(p, X, (write('error from p'), nl)).
will illustrate the ecxeption handling.
I played with a few other examples which I found. This might be usefull.
p :- throw(b).
r(X) :- throw(X).
q:- catch(p, B, format('Output1: Error from throwing p')), r(B).
catch(throw(exit(1)), exit(X), format('Output: `w', [X])).
Output: 1
1 is thrown to catcher 'exit(X)' and recovered by format('Output: ~w', [X])),
catch(p, C, format('hellop')).
Output: hellop
p throws 'b' which is recovered by writing 'hellop'
catch(q, C, format('Output2, Recovering q: helloq ')).
Output1: Error from throwing p
Output2, Recovering q: helloq
Ben
The stderr stream is aliased to user_error (see https://www.swi-prolog.org/pldoc/man?section=streamalias )
You can write a term (like a string) to a stream using write/2.
You can stop the program using halt.
For example:
% Happy case. Comes first, uses ! to avoid taking the alternative branch
foo(X) :- bar(X, Y), baz(Y), !.
% Fallback branch, in case the above failed. Writes a message and halts.
foo(X) :-
write(user_error, "Couldn't foo"),
halt.

Resources