reeves@ucla-cs.UUCP (10/22/87)
I'm having a problem reading forall/2 and wondered if anyone could help. In Sterling and Shapiro p. 270-271, the claim is that forall(Goal,Condition) is true for all solutions of Goal, Condition is true. Under this reading not(Goal, not(Condition)) works fine as far as I can tell. They claim that forall(father(X,C),male(C)) is checking _for_ fathers that have all male children. My reading is that it is checking _that_ all fathers have all male children. Their implementation returns two solutions for the query: the fathers that have only male children. In the database, however, there are fathers who do not have only male children, so (I would think) the query should fail. Is there a reading for forall/2 for the following implementation (from S&S)? forall(G,C) :- setof(C,G,Cases), check(Cases). check([Case|Cases]) :- Case, check(Cases). check([]). Alternatively, is there a case where: forall(G,C) :- not(G, not C). behaves counterintuitively, due to the use of not as negation-as-failure? Fanx, John Reeves UCLA CS Department, AI Lab UUCP: {ihnp4,ucbvax}!ucla-cs!reeves 3531 Boelter Hall, LA CA 90024 ARPA: reeves@CS.UCLA.EDU
lee@mulga.oz (Lee Naish) (10/26/87)
In article <8781@shemp.UCLA.EDU> reeves@CS.UCLA.EDU (John F. Reeves) writes: >I'm having a problem reading forall/2 and wondered if anyone could help. > > forall(father(X,C),male(C)) > >....Alternatively, is there a case where: > > forall(G,C) :- not(G, not C). > >behaves counterintuitively, due to the use of not as negation-as-failure? BTW, it should be not (G, not C) or not((G, not C)). forall has the same problems as \+ (not) in most Prolog systems. It is not logical. Even its name has an operational flavor rather than a declarative one. It should be logical and be called implies, or => (declared as an operator, of course). Also, there should be a way of stating the quantification of variables. In NU-Prolog you can write all C father(X,C) => male(C) % all children X fathered are male or all X father(X,C) => male(C) % meaningful but not useful These are both compiled into the not not form, which delays until the unquantified variables are ground (hence it is sound). If the construct appears in a predicate declared 'pure', further transformation may be done by the compiler. For example all [C,S] (father(X, C), sex(X, S) => S ~= female) is currently compiled into all [C,S] not (S = female, father(X, C), sex(X, S)) (we could do better, of course) This is all very easy to implement and every Prolog system should have it (if the system doesnt support delaying then it should write error messages instead). It really is useful for programming - it makes programming easier and programs much more readable. It is also useful for teaching. Here is an game playing example from Bratko (p 360): win(Pos) :- not terminallost(Pos), move(Pos, Pos1), not ( move(Pos1, Pos2), not won(Pos2)). The last two lines should be all Pos2 move(Pos1, Pos2) => won(Pos2). Which do you think is easier to understand? I have just finished teaching an introductory AI/logic programming course. For the first time, students have not been (ab)using cut. Although some of the programming style has not been great (overuse of if-then-else being the most common flaw), we consider this to be a significant advance. A major reason for it is the higher level logical constructs which are available. The aggregate functions (sum, count etc) which Philip Dart mentioned on the network recently were also used more than I expected. It seems that they are another worthwhile logical extension to Prolog. lee