Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog Negation

I am trying to solve a simple query in Prolog that uses negation but I can't crack it. The query is "Find the categories that have never been sold".

The knowledge base is as follows:

category(stationery, 30, 200, 10, 2).
category(books, 10, 30, 3, 2).
category(consumables, 50, 300, 15, 3).

item(pen, stationery, 10, 150).
item(colgate_small, consumables, 20, 65).
item(colgate_medium, consumables, 45, 70).
item(colgate_big, consumables, 70, 34).
item(juice_small, consumables, 45, 23).
item(juice_medium, consumables, 60, 23).
item(juice_big, consumables, 80, 12).
item(book, stationery, 5, 65).
item(pencil, stationery, 7, 56).
item(newspaper, books, 50, 400).

sale(tom, 1/1/07, pen, 3).
sale(peter, 1/1/07, book, 85).
sale(peter, 1/1/07, juice_small,1).
sale(alice, 7/1/07, pen, 10).
sale(alice, 7/1/07, book, 5).
sale(patrick, 12/1/07, pen, 7).
like image 510
crazywizard Avatar asked Mar 29 '11 12:03

crazywizard


People also ask

How do you negate a function in Prolog?

Negation in Prolognot(B) can also be written as \+ B. – And not(X=Y) can also be written as X \= Y. The goal \+ X succeeds iff X fails.

How do I stop Prolog?

If you want to exit SWI-Prolog, issue the command halt., or simply type CTRL-d at the SWI-Prolog prompt.

What is cut and fail in Prolog?

In the body of that clause, we are trying to satisfy the goal, the goal obviously fails. But here the cut prevents it from backtracking the system, so the goal can_fly(penguins) fails. Cut with failure is the combination of fail and goals !. Next TopicMap Coloring in Prolog. ← prev next →

How do you write not equal to in Prolog?

Syntax of Prolog not equalValue1 =\= Value2. Explanation: The “=\=” sign is used to determine not equal values. This operator is mostly used for numerical values and arithmetic operations.


1 Answers

Sam Segers answer is correct, though it will give you the list of categories not sold. If you don't want an aggregation but rather a predicate which will backtrack over all the categories which do not have any items sold you would write something like this:

not_sold(Cat):-
 category(Cat,_,_,_,_),  % Get one category at a time
 \+ (    % Applies negation
   item(Item, Cat,_,_),  % Check for items in this category
   sale(_,_,Item,_)      % Has the item been sold ?
 ).

This predicate, upon backtracking, will yield all the categories for which no items where sold.

like image 68
gusbro Avatar answered Sep 28 '22 10:09

gusbro