Home > Archive > Prolog > August 2005 > Newbie question...simple rule question...
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Newbie question...simple rule question...
|
|
|
| Dear All,
I am trying to understand the best way to write a rule which checks on
all the elements.
-------------
people(a).
people(c).
ok(b).
ok(a).
everybodyok_works :- findall(X,ok(X),List),maplist(people,Lis
t).
everybodyok_bad :- people(X),ok(X).
-------------
What am I missing? Is there a better way to write rule which says:
"Everybody is ok if for all people we know has said they are OK." ?
Thanks in Advance,
Mans
| |
| Jan Wielemaker 2005-08-11, 9:03 am |
| On 2005-08-11, mans <mshapshak@gmail.com> wrote:
> Dear All,
>
> I am trying to understand the best way to write a rule which checks on
> all the elements.
>
> -------------
> people(a).
> people(c).
> ok(b).
> ok(a).
>
> everybodyok_works :- findall(X,ok(X),List),maplist(people,Lis
t).
>
> everybodyok_bad :- people(X),ok(X).
>
> -------------
>
> What am I missing? Is there a better way to write rule which says:
> "Everybody is ok if for all people we know has said they are OK." ?
Prolog tries to find instances that satisfy some condition. Think
from the other side. Everybody is ok iff there is nobody who is not
ok.
Cheers --- Jan
| |
|
| Dear Jan,
Thanks for you quick reply.
I am trying to make my prolog as similar to the natural language as
possible and hence deal with the way the actual user is
thinking...which in this case may be the reverse of the way prolog
thinks??.
But in any case how about this if I stick withe same input
declarations:
notok(X) :- \+ok(X).
everybodyok_new :- not((people(X),notok(X))).
Which seems to work..although I am not sure what the meta call means:
[trace] 125 ?- everybodyok_new.
Call: (7) everybodyok_new ? creep
^ Call: (8) not((people(_G506), notok(_G506))) ? creep
Call: (10) people(_G506) ? creep
Exit: (10) people(a) ? creep
Call: (10) notok(a) ? creep
Call: (11) ok(a) ? creep
Exit: (11) ok(a) ? creep
Fail: (10) notok(a) ? creep
Redo: (10) people(_G506) ? creep
Exit: (10) people(c) ? creep
Call: (10) notok(c) ? creep
Call: (11) ok(c) ? creep
Fail: (11) ok(c) ? creep
Exit: (10) notok(c) ? creep
Exit: (9) '<meta-call>'((people(c), notok(c))) ? creep
^ Fail: (8) not((people(_G506), notok(_G506))) ? creep
Fail: (7) everybodyok_new ? creep
Thanks again!
Mans
| |
| Jan Wielemaker 2005-08-11, 5:03 pm |
| On 2005-08-11, mans <mshapshak@gmail.com> wrote:
> Dear Jan,
>
> Thanks for you quick reply.
>
> I am trying to make my prolog as similar to the natural language as
> possible and hence deal with the way the actual user is
> thinking...which in this case may be the reverse of the way prolog
> thinks??.
>
> But in any case how about this if I stick withe same input
> declarations:
>
> notok(X) :- \+ok(X).
> everybodyok_new :- not((people(X),notok(X))).
>
> Which seems to work..although I am not sure what the meta call means:
>
> [trace] 125 ?- everybodyok_new.
> Call: (7) everybodyok_new ? creep
> ^ Call: (8) not((people(_G506), notok(_G506))) ? creep
> Call: (10) people(_G506) ? creep
> Exit: (10) people(a) ? creep
> Call: (10) notok(a) ? creep
> Call: (11) ok(a) ? creep
> Exit: (11) ok(a) ? creep
> Fail: (10) notok(a) ? creep
> Redo: (10) people(_G506) ? creep
> Exit: (10) people(c) ? creep
> Call: (10) notok(c) ? creep
> Call: (11) ok(c) ? creep
> Fail: (11) ok(c) ? creep
> Exit: (10) notok(c) ? creep
> Exit: (9) '<meta-call>'((people(c), notok(c))) ? creep
This is an artifact introduced by SWI-Prolog to deal with complex
goals (i.e. goals with control structures) given to call/1, once/1,
etc.
> ^ Fail: (8) not((people(_G506), notok(_G506))) ? creep
> Fail: (7) everybodyok_new ? creep
Now that you understand this, you are ready for the more
readable form:
everybodyok :- forall(people(X), ok(X)).
And for the definition of forall/2 (a built-in):
forall(Cond, Action) :-
\+ (Cond, \+ Action).
Enjoy --- Jan
| |
|
| Jan,
Thanks!
Mans
P=2ES. Just out of curiosity. Internally does prolog use go through the
list similar to findall(X,ok(X),List),maplist(=ADpeople,
List).?
| |
| Jan Wielemaker 2005-08-11, 5:03 pm |
| On 2005-08-11, mans <mshapshak@gmail.com> wrote:
> Jan,
> Thanks!
> Mans
> P.S. Just out of curiosity. Internally does prolog use go through the
> list similar to findall(X,ok(X),List),maplist(-people,List).?
No :-) \+/1 can be implemented as
\+(G) :- G, !, fail.
\+(_).
In fact the compiler handles \+, but that doesn't change things too much.
Cheers --- Jan
| |
| Mauro Di Nuzzo 2005-08-12, 9:01 am |
| Try this, and let me know if it works please:
everybodyok :- (
people(X),
( ok(X)
-> fail
; !, fail
)
; true
).
Regards,
M
"mans" <mshapshak@gmail.com> ha scritto nel messaggio
news:1123762484.841598.229320@g44g2000cwa.googlegroups.com...
> Dear All,
>
> I am trying to understand the best way to write a rule which checks on
> all the elements.
>
> -------------
> people(a).
> people(c).
> ok(b).
> ok(a).
>
> everybodyok_works :- findall(X,ok(X),List),maplist(people,Lis
t).
>
> everybodyok_bad :- people(X),ok(X).
>
> -------------
>
> What am I missing? Is there a better way to write rule which says:
> "Everybody is ok if for all people we know has said they are OK." ?
>
> Thanks in Advance,
> Mans
>
|
|
|
|
|