I think your representation of knowledge into Prolog is a little indirect. Let's start with your assumptions:
1) the universe has only 3 types of shapes: triangle, circle and quadrilateral.
This indicates we might want to define a fact/predicate called shape
and assert three of them:
shape(triangle).
shape(circle).
shape(quadrilateral).
If you then query, shape(X)
(X
is a shape), Prolog will respond with:
X = triangle
X = circle
X = quadrilateral
2) a quadrilateral can either be a square or a rectangle (NOT BOTH).
Assumption #1 says there are only three shapes: triangle, circle, or quadrilateral. But assumption #2 violates assumption #1. Let's suppose we fix this by adding a couple more shapes:
shape(square).
shape(rectangle).
Then we can include, for example:
kind(rectangle, quadrilateral).
kind(square, rectangle).
kind_of(X, Y) :- kind(X, Y).
kind_of(X, Y) :- kind(X, Z), kind(Z, Y).
Then kind_of(square, rectangle)
is true, kind_of(rectangle, quadrilateral)
is true, and kind_of(square, quadrilateral)
is true.
| ?- kind_of(X, Y).
X = rectangle
Y = quadrilateral ? ;
X = square
Y = rectangle ? ;
X = square
Y = quadrilateral
yes
The original assumption is also a flawed in that a square is, indeed, a type of rectangle. So a quadrilateral can be both a square and a rectangle if it is square.
3) anything with colour may NOT be a quadrilateral, but a quadrilateral MUST have either RED or YELLOW colour ONLY.
This is a little unclear. By may, do you mean may or may not? Or do you mean must? If must, then this is clearly a contradiction. So I assume this means may or may not?
You need to introduce valid colors. One way would be:
color(red).
color(yellow).
color(black).
...
You can indicate what valid colors a shape has:
shape_color(quadrilateral, red).
shape_color(quadrilateral, yellow).
shape_color(triangle, X) :- color(X). % a triangle can be any valid color
4) a square is the ONLY quadrilateral that has 4 equal sides
Refer back to my comment in #2. There needs to be some information about dimensions or other detailed shape attributes. One could go so far as to have the attributes be part of each shape (e.g., square(S)
for a square of side length S
, or triangle(S1,S2,S3)
for a triangle with the given side lengths). I'll assume, though, you only want to refer to the shapes generically. So we need facts about their geometry. How you define these and how detailed they are depends totally upon your needs. But to keep things simplistic:
equal_sides(square, 4). % all 4 sides equal
equal_sides(rectangle, 2). % opposing 2 sides equal
A query to equal_sides(square, 4).
would be true,
5) a triangle is the ONLY shape with 3 edge.
This could be done using a set of facts about how many sides a shape has:
sides(triangle, 3).
sides(square, 4).
sides(rectangle, 4).
sides(quadrilateral, 4).
6) triangle, circle and quadrilateral are all distinct, and can be ONLY either one (i.e, no overlapping of properties).
This occurs naturally from all of the above.
The above approach could support a number of queries and other predicates. If you have a variable, Shape
, you can ask if it's a valid shape with, shape(Shape).
. You can also see if it's a "kind of" something else via, kind_of(Shape, Kind).
More specifically, you can ask if a shape is a kind of quadrilateral by, kind_of(Shape, quadrilateral).
The query, kind_of(circle, rectangle)
would come back false (a circle is not a rectangle, or even a kind of rectangle). The query, sides(rectangle, 3).
is false.
Regarding dimensional information, if you were interested in representing specific objects, like a circle of a given radius, or a rectangle of given side lengths, you could augment the representation of a shape to include these attributes. For example, instead of just circle
you could have circle(R)
where R
is the radius in some arbitrary units. A rectangle could be rectangle(L, W)
, etc. Your shape
facts could look like, shape(circle(_)). shape(quadrilateral(_,_,_,_)).
etc.
How you implement this depends heavily upon how you want to use it. But the most important thing is deciding on reasonable ways of representing the knowledge, and then representing the rules. Also, in general, I would try to avoid defining a rule in terms of a conjunction of negations (\+
) and try to define things in a positive way, and let the absence of a rule or fact result in failure.