SWI-Prolog / swish

SWI-Prolog for SHaring: a SWI-Prolog web IDE
Other
503 stars 128 forks source link

SWISH reporting arguments not suff. instantiated, while local install runs. #22

Open Anniepoo opened 8 years ago

Anniepoo commented 8 years ago

This program behaves differently in SWISH.

http://swish.swi-prolog.org/p/familyrelationships.pl

In SWISH running the example query results in Arguments are not sufficiently instantiated. Placing a breakpoint on the member call in the main predicate produces the puzzling behavior

Breakpoint 33 in 1-st clause of query_family/3 at src:80 Arguments are not sufficiently instantiated

when run on 7.3.11 local install on my machine it runs fine.

Strangely, removing the call fixes it. But one of two things is an error here. a) This is a bug in SWISH b) The error messages are opaque to me. In particular, I'd discourage printing error messages without the file/line number.

additionally, it's very strange that the breakpoint doesn't actually cause the program to stop and show the debugger icons.

Since the program might change online, here's the repro version

male(dada). male(nana). male(abhishek). male(tilak). male(raghav).

female(dadi). female(nani). female(rachna). female(rita). female(didi). female(katrina).

spouse(dada, dadi). spouse(dadi, dada). spouse(nana, nani). spouse(nani, nana). spouse(tilak, rachna). spouse(rachna, tilak). spouse(raghav, katrina). spouse(katrina, raghav).

parent(dada, tilak). parent(nana, rachna). parent(nana, rita). parent(nana, abhishek). parent(tilak, raghav). parent(tilak, didi). parent(dadi, tilak). parent(nani, rachna). parent(nani, rita). parent(nani, abhishek). parent(rachna, raghav). parent(rachna, didi).

husband(Husband, Woman) :- spouse(Husband, Woman). wife(Wife, Man) :- female(Wife), spouse(Wife, Man).

father(Father, Child) :- male(Father), parent(Father, Child). mother(Mother, Child) :- female(Mother), parent(Mother, Child).

son(Son, Parent) :- male(Son), parent(Parent, Son). daughter(Daughter, Parent) :- female(Daughter), parent(Parent, Daughter).

sister(Sister, Y) :- female(Sister), mother(Mother, Sister), mother(Mother, Y), Sister \= Y. brother(Brother, Y) :- male(Brother), mother(Mother, Brother), mother(Mother, Y), Brother \= Y.

father_in_law(FIL, Y) :- male(FIL), spouse(Husband, Y), parent(FIL, Husband). mother_in_law(MIL, Y) :- female(MIL), spouse(Husband, Y), parent(MIL, Husband).

son_in_law(SIL, Y) :- male(SIL), spouse(Daughter, SIL), parent(Y, Daughter). daughter_in_law(DIL, Y) :- female(DIL), spouse(Son, DIL), parent(Y, Son).

paternal_grandfather(Grandfather, Y) :- male(Grandfather), father(Father, Y), parent(Grandfather, Father), parent(Father, Y). paternal_grandmother(Grandmother, Y) :- female(Grandmother), father(Father, Y), parent(Grandmother, Father), parent(Father, Y).

paternal_grandson(Grandson, Grandparents) :- parent(Grandparents, Son), father(Son, Grandson), male(Grandson). paternal_granddaughter(Granddaughter, Grandparents) :- parent(Grandparents, Son), father(Son, Granddaughter), female(Granddaughter).

maternal_grandfather(Grandfather, Y) :- male(Grandfather), mother(Father, Y), parent(Grandfather, Father), parent(Father, Y). maternal_grandmother(Grandmother, Y) :- female(Grandmother), mother(Father, Y), parent(Grandmother, Father), parent(Father, Y).

maternal_grandson(Grandson, Grandparents) :- parent(Grandparents, Son), mother(Son, Grandson), male(Grandson). maternal_granddaughter(Granddaughter, Grandparents) :- parent(Grandparents, Son), mother(Son, Granddaughter), female(Granddaughter).

sister_in_law(SIL, Y) :- spouse(X, Y), sister(SIL, X). brother_in_law(BIL, Y) :- spouse(X, Y), brother(BIL, X).

query_family(P1, P2, P) :- member(P, [father, mother, father_in_law, mother_in_law, paternal_grandfather, paternal_grandmother, maternal_grandfather, maternal_grandmother, husband, wife, son, daughter, sister, brother]), call(P, P1, P2).

/\

?- query_family(raghav, katrina, Relation).

*/

Anniepoo commented 8 years ago

IIRC the mysterious 'args not instantiated' message was given out by an old version of pengines? I remember struggling with it before.

JanWielemaker commented 8 years ago

Hi Anne,

The problem is indeed the call/3. The sandbox cannot figure out what this is calling by lack of information. Of course actually by not looking deep enough, but it is unclear whether looking deeper is a good idea because it makes the border between what it considers safe and what not vaguer.

All debugging attempts are futile because it doesn't even start executing.

The message surely needs to be improved, at least by claiming it is produced by the sandbox. Ideally it would of course say something like "I cannot execute your program because I cannot derive what is called by call/3 at line 83".

That will require some work :(

Cheers --- Jan

On 12/13/2015 12:22 AM, Anne Ogborn wrote:

This program behaves differently in SWISH.

http://swish.swi-prolog.org/p/familyrelationships.pl

In SWISH running the example query results in Arguments are not sufficiently instantiated. Placing a breakpoint on the member call in the main predicate produces the puzzling behavior

Breakpoint 33 in 1-st clause of query_family/3 at src:80 Arguments are not sufficiently instantiated

when run on 7.3.11 local install on my machine it runs fine.

Strangely, removing the call fixes it. But one of two things is an error here. a) This is a bug in SWISH b) The error messages are opaque to me. In particular, I'd discourage printing error messages without the file/line number.

additionally, it's very strange that the breakpoint doesn't actually cause the program to stop and show the debugger icons.

Since the program might change online, here's the repro version

male(dada). male(nana). male(abhishek). male(tilak). male(raghav).

female(dadi). female(nani). female(rachna). female(rita). female(didi). female(katrina).

spouse(dada, dadi). spouse(dadi, dada). spouse(nana, nani). spouse(nani, nana). spouse(tilak, rachna). spouse(rachna, tilak). spouse(raghav, katrina). spouse(katrina, raghav).

parent(dada, tilak). parent(nana, rachna). parent(nana, rita). parent(nana, abhishek). parent(tilak, raghav). parent(tilak, didi). parent(dadi, tilak). parent(nani, rachna). parent(nani, rita). parent(nani, abhishek). parent(rachna, raghav). parent(rachna, didi).

husband(Husband, Woman) :- spouse(Husband, Woman). wife(Wife, Man) :- female(Wife), spouse(Wife, Man).

father(Father, Child) :- male(Father), parent(Father, Child). mother(Mother, Child) :- female(Mother), parent(Mother, Child).

son(Son, Parent) :- male(Son), parent(Parent, Son). daughter(Daughter, Parent) :- female(Daughter), parent(Parent, Daughter).

sister(Sister, Y) :- female(Sister), mother(Mother, Sister), mother(Mother, Y), Sister \= Y. brother(Brother, Y) :- male(Brother), mother(Mother, Brother), mother(Mother, Y), Brother \= Y.

father_in_law(FIL, Y) :- male(FIL), spouse(Husband, Y), parent(FIL, Husband). mother_in_law(MIL, Y) :- female(MIL), spouse(Husband, Y), parent(MIL, Husband).

son_in_law(SIL, Y) :- male(SIL), spouse(Daughter, SIL), parent(Y, Daughter). daughter_in_law(DIL, Y) :- female(DIL), spouse(Son, DIL), parent(Y, Son).

paternal_grandfather(Grandfather, Y) :- male(Grandfather), father(Father, Y), parent(Grandfather, Father), parent(Father, Y). paternal_grandmother(Grandmother, Y) :- female(Grandmother), father(Father, Y), parent(Grandmother, Father), parent(Father, Y).

paternal_grandson(Grandson, Grandparents) :- parent(Grandparents, Son), father(Son, Grandson), male(Grandson). paternal_granddaughter(Granddaughter, Grandparents) :- parent(Grandparents, Son), father(Son, Granddaughter), female(Granddaughter).

maternal_grandfather(Grandfather, Y) :- male(Grandfather), mother(Father, Y), parent(Grandfather, Father), parent(Father, Y). maternal_grandmother(Grandmother, Y) :- female(Grandmother), mother(Father, Y), parent(Grandmother, Father), parent(Father, Y).

maternal_grandson(Grandson, Grandparents) :- parent(Grandparents, Son), mother(Son, Grandson), male(Grandson). maternal_granddaughter(Granddaughter, Grandparents) :- parent(Grandparents, Son), mother(Son, Granddaughter), female(Granddaughter).

sister_in_law(SIL, Y) :- spouse(X, Y), sister(SIL, X). brother_in_law(BIL, Y) :- spouse(X, Y), brother(BIL, X).

query_family(P1, P2, P) :- member(P, [father, mother, father_in_law, mother_in_law, paternal_grandfather, paternal_grandmother, maternal_grandfather, maternal_grandmother, husband, wife, son, daughter, sister, brother]), call(P, P1, P2).

/**

?- query_family(raghav, katrina, Relation).

*/

— Reply to this email directly or view it on GitHub https://github.com/SWI-Prolog/swish/issues/22.

Anniepoo commented 8 years ago

Agreed, the sane alternative is a better error message. From a UX standpoint, the issue is the lack of 'this is from the sandbox'. Can we just trap the exception and decorate it after the fact?

Anniepoo commented 8 years ago

Of course actually by not looking deep enough, but it is unclear whether looking deeper is a good idea because it makes the border between what it considers safe and what not vaguer.

Isn't it just 'safe if what I'm calling is safe'?

TeamSPoon commented 8 years ago

Just wanted to let you all know i am experiencing the same problems in 7.3.13 with random programs claiming Arguments are not sufficiently instantiated with call/3 . Sorry to be so vague myself! For example I was using it inside of when/2. Wen I collect more information or a smaller reproduction i'll try to help.

(Mine all happen outside of swish and web)

Anniepoo commented 8 years ago

interesting. Doublas, can you try running the original student program in 7.3.13? It runs fine in 7.3.11

TeamSPoon commented 8 years ago

Original student program fine on my console 7.3.13

Starting program: /usr/local/bin/swipl -f src/sp.pl
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.13-43-ga337704-DIRTY)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.

For help, use ?- help(Topic). or ?- apropos(Word).

?- query_family(raghav, katrina, Relation).
Relation = husband ;
false.

?- call(query_family(raghav, katrina, Relation)).
Relation = husband ;
false.

?- call(query_family,raghav, katrina, Relation).
Relation = husband ;
false.

?- query_family(raghav, R1, Relation).
R1 = katrina,
Relation = husband ;
R1 = tilak,
Relation = son ;
R1 = rachna,
Relation = son ;
R1 = didi,
Relation = brother ;
false.

?- call_cleanup(query_family(raghav, R1, Relation),true).
R1 = katrina,
Relation = husband ;
R1 = tilak,
Relation = son ;
R1 = rachna,
Relation = son ;
R1 = didi,
Relation = brother ;
false.

?- call_cleanup(true,query_family(raghav, R1, Relation)).
R1 = katrina,
Relation = husband.

However any little anything will cause (or hide the call/3 problem)

For example I had a program that looked like...

w_mvars(G):-  
    '$sinkmode'(W,W),
     T is W   /\ \ 4096, 
     '$sinkmode'(W,T), 
     call_cleanup(G,'$sinkmode'(_,W)).

I had this problem so I had to change it to

w_mvars(G):- 
       '$sinkmode'(W,W),
      T is W   /\ \ 4096, 
      '$sinkmode'(W,T),  
  (G *-> '$sinkmode'(_,W);
       ('$sinkmode'(_,W),fail)).

To hide the problem.

All changes I make to hide the problem seem to be adding or removing unrelated things making me suspect it's managing a trail that is now slightly off in some conditions.

This next bit might be TMI (too much information)

I was hacking the in C tje order that attributed variables unify with non attributed variables and had a testcase when I first encountered it. So I blamed myself instead


accume:attr_unify_hook(Prev,Value):-
  writeq(accume_unify(M,Prev,Value)),nl,
  accume_unify_hook(Prev,Value).

accume_unify_hook(init_accumulate(Var,M,P),Value):- nonvar(Value),!,put_attr(Var,accume,accume_value(Var,M,P,Value)).
accume_unify_hook(init_accumulate(Var,M,P),Value):- var(Value),!,Value=_.  
accume_unify_hook(accume_value(Var,M,P,Prev),Value):- nonvar(Value),!,show_call(must(call(P, Prev,Value,Combined))),put_attr(Var,accume,accume_value(Var,M,P,Combined)).
accume_unify_hook(accume_value(Var,_M,P,Prev),Value):- var(Value),!, nonvar(P),
    %% must('$sinkmode'(W,W))),must((T is W  \/ 4096)), must('$sinkmode'(W,T)),
     must(wno_mvars_tst(Prev=Value)).

my call(P, Prev,Value,Combined)..

was being called with

call(_L666,_L667,_L668)

sometimes

TeamSPoon commented 8 years ago

t didn't reproduce with your program this hour .. but with some unrelated fiddling to other code loading .. your program would finally reproduce

I think it is much deeper in the interpreter a very elusive bug to track down.

Too bad I was able to rehide perfect reproducible happenings on my machine at least 5 times (that is i got the call/3 reliably) except when i changed my use of call_cleanup.

I would start out thinking somehow variables are being undone before their time, How? Some "interrupting event code" is using the local lTop incorrectly Some code is wearing a halo by opening a foreign frame, however that halo was crooked, since a close_foreign_frame is wiping out too many references on stack (they are becoming variables again. setVar(..)) If it is not some interrupting code, then delayed code (save/restoreWakup), or even cleanup code. Though I though I dont blame that code, I'd blame the non delayed code/ non foreign-frame code doing polluting the ecosystem and setting up the close_foreign_frame trap shots.

We'd think it is call/N mainly because it gripes the loudest with a "Arguments are not sufficiently instantiated" and is the most sensitive it" goes unnoticed the other times it is happening. (it == the overzealous setVar(...) ).

NEWS

I am editing this comment.. I just got

ERROR: setup_call_catcher_cleanup/4: Arguments are not sufficiently instantiated

Realized if anything i just said above was a reality (probably not) at least in my case this happening NOT in the running the program time.. BUT source code loading time due to a term expansion make the variables different.

?- listing(wno_dbg/1).

:- meta_predicate wno_dbg(0).

wno_dbg(_) :-
        '$sinkmode'(_, _),
        _ is _ /\ \ 16777216,
        '$sinkmode'(_, _),
        call_cleanup(_, '$sinkmode'(_, _)).

It should have said something closer to ...


wno_dbg(G):-  
   '$sinkmode'(W,W),
    T is W /\ \ 16777216 , 
   '$sinkmode'(_,T), 
    call_cleanup(G,'$sinkmode'(_,W)).

so Annie..

?- listing(query_family/3).

and see if it did not convert your vars to _

JanWielemaker commented 8 years ago

Note that the instantiation errors have nothing to do with running the code. It is purely the sandbox analysis that decides it doesn't know that a meta-call is safe because it has insufficient information about it. If you compare to normal execution, you must load the program and call

  ?- safe_goal(MyGoal).

There are no recent changes to the sandbox code except for some newly declared safe predicates and a time limit imposed by library(pengines) as some programs are really hard to prove. It comes back with a time limit exceeded message though. This message nicely indicates it results from the sandbox analysis.

Anniepoo commented 8 years ago

Douglas seems to think that it's not related to sandbox at all. ?

JanWielemaker commented 8 years ago

I would be very surprised if this was the case ...

TeamSPoon commented 8 years ago

Well I had wanted to think it was more... See this Link https://github.com/SWI-Prolog/swish/issues/22 (since some of the thread missed the emails )

But by the end of what I had written, (below "NEWS") I say that I was wrong about what is above "NEWS" :)

My case (which is a different issue (since it was outside the sandbox)) came down to a term_expansion related problem when I was loading.

So back to Annie's code/problem.. it amounts to this..

mother(bill,sue).
who_loves(X,Y):- P=mother,call(P,X,Y).

/*
?-  who_loves(X,Y).
*/

On Mon, Dec 14, 2015 at 11:30 AM, Jan Wielemaker notifications@github.com wrote:

I would be very surprised if this was the case ...

— Reply to this email directly or view it on GitHub https://github.com/SWI-Prolog/swish/issues/22#issuecomment-164535494.

JanWielemaker commented 8 years ago

Ok. I think we came to the conclusion that this is not acceptable by the sandbox and only a better error message is reachable. At some point I may investigate rewriting the program into safe_call(P,X,Y). That isn't really trivial though.