0

I am working on a dictionary-like program with prolog, and my code goes like this:

define(car,vehicle).
define(car,that).
define(car,has).
define(car,four).
define(car,wheels).
define(wheels,round).
define(wheels,object).
define(wheels,used).
define(wheels,in).
define(wheels,transportation).


defined(X):-define(X,_).

anotherdefined(X):- \+ undefined(X).
undefined(X):- \+define(X,_).        

I am trying to write a defined/1 predicate which will give me:

?-defined(X).
X = car ;
X = wheels ;
false.

Yet, my defined/1 gives me X=car. five times (naturally) for everytime it counters define(car,_). and my anotherdefined/1 gives me only true. What is the method to stop prolog backtracking to the other instances of define(car,_).,and skip to define(wheels,_).?

Edit: I have written the following lines to get the result I want with givedefinedword/1,

listdefined(X):-findall(Y,defined(Y),Z),sort(Z,X).
givedefinedword(X):-listdefined(List),member(X,List).

However since I wanted an efficient predicate (which I will use in many others) it beats the purpose. This predicate does too much process.

Or, Would it be better to use a predicate that modifies the code? say prepares a list of defined words, and modifies it when new definitions are added.

Thanks.

Meric Usta
  • 15
  • 3

2 Answers2

0

If you change define to relate items and lists, like

definelist(car, [vehicle, that, has, four, wheels]).
% etc.
defined(X) :- definelist(X, _).

then defined will no longer produce duplicates, nor require linear space.

Of course, a query define(X, Y) must now be performed as definelist(X, L), member(Y, L). If you want this to be efficient as well, you may need to duplicate all definitions.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • Thank you, I think it is time for me to start thinking in terms of Lists. What do you mean by "you may need to duplicate all definitions"? – Meric Usta Oct 23 '14 at 01:32
  • @MericUsta That you'd `define(car, vehicle)` as well as my suggested `definelist`, and put all definitions in both predicates. I don't actually recommend that, but if speed is important, there are ways to automate it so you don't have to duplicate everything by hand. – Fred Foo Oct 23 '14 at 07:03
0

What are you trying to achieve with your program? It seems that you want to have facts in the form:

"A car is a vehicle that has four wheels"

"Wheels are round objects used in transportation" (a bit vague)

How are you going to use these facts? @larsmans suggestion if perfectly fine, if you want to just have your statement as a "sentence". It really depends what you will do with the information though.

Consider structuring the information in your database:

is(car, vehicle).
is(bicycle, vehicle).
is(boat, vehicle).
has(car, wheel(four)).
has(car, motor).
has(bicycle, wheel(two)).

Given this database, you can at least ask a question like, "what vehicles are there?", "does a bicycle have a motor?", or maybe, "how many wheels does a car have?", or "which vehicles have no wheels?"

?- is(X, vehicle).
?- has(bicycle, motor).
?- has(car, wheel(N)).
?- is(X, vehicle), \+ has(X, wheel(_)).

and so on.

Once you have defined your problem better, you can define your data structures better, which will make writing a program to solve your problem easier.

  • Thank you for the comments, it gives me some good insights. Right now I am more concerned about the definitions of words.. (currently just bogus definitions of course) But it might come to categorizing later as well. – Meric Usta Oct 23 '14 at 01:37