0
votes

as a beginner in prolog with only previous knowledge in Java programming, I find it hard to relate a logic into a prolog rule...

Below is what I have this far, and I would like anyone to point out where I went wrong, considering the results that I got.

shapes(X):-triangle(X); circle(X); quadrilateral(X); withColour(X).

square(sq).
rectangle(rect).
circle(cir).
triangle(tri).
quadrilateral(X).

quadrilateral(X):-square(X).
quadrilateral(X):-rectangle(X).

red(X):-quadrilateral(X).
yellow(X):-quadrilateral(X).

withColour(X):-red(X).
withColour(X):-yellow(X).

fourEqualside(square(X),length).

quadrilateral(X):- \+triangle(X), \+circle(X), shapes(X).

triangle(X):-hasThreeEdge(X).
triangle(X):- \+circle(X), \+rectangle(X), \+withColour(X), shapes(X), hasThreeEdge(X).

circle(X):-\+quadrilateral(X), \+triangle(X),\+withColour(X), shapes(X).

The below are my assumptions:

1) the universe has only 3 types of shapes: triangle, circle and quadrilateral.

2) a quadrilateral can either be a square or a rectangle (NOT BOTH).

3) anything with colour may NOT be a quadrilateral, but a quadrilateral MUST have either RED or YELLOW colour ONLY.

4) a square is the ONLY quadrilateral that has 4 equal sides

5) a triangle is the ONLY shape with 3 edge.

6) triangle, circle and quadrilateral are all distinct, and can be ONLY either one (i.e, no overlapping of properties).

The below is what I have when I query the prolog source.

1) circle(tri). -false (in red).

2) circle(rect). false (in red).

3) circle(cir). true without '.' (in black), false in red.

4) quadrilateral(rect). true (black), true (black), out of local stack (red)

5) quadrilateral(cir). true (black), false (red)

6) quadrilateral(tri). true (black), false (red)

7) triangle(rect). false (red)

8) triangle(cir). false (red)

9) triangle(tri). true (black) false (red)

10) hasThreeEdge(rect). ERROR. top-level undefined procedure: swim/1 (red) <- what does this mean? answer is same when i query circle and triangle too!

This seems like there is something that I've done wrong...

1
The best thing to do is forget what you know about Java (or any other imperative language) altogether and learn Prolog as if it's your first programming language. Otherwise, it's too tempting to force Prolog to be imperative, which leads to trouble. :)lurker
Assumption #2 violates assumption #1. It introduces two new shapes, square and rectangle, which are not part of your shape universe stipulated in #1. It is, therefore, an invalid (illogical) assumption.lurker
What I was trying to put across is that rectangle and square is a subset of quadrilateral shape. How can I fix that part?user3004159

1 Answers

0
votes

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.