Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Make a variable to a string 1

Status
Not open for further replies.

Kazzal

Programmer
Nov 6, 2009
10
AU
I am having trouble with this code, are you able to assign a variable to a string or is IS reserved for a comparison or something?

Here is the code, Im just trying to make the internal goal "least" show the least powerful car.

% cars/5.
% cars(BRAND,MANUFACTURER,YEAR,POWER,ENGINE).

cars('Camery','Hiyundi','1980',500,'2l').
cars('Ford XL','Hiyundi','1950',900,'5l').
cars('Tourino','Ford','1920',450,'3l').
cars('Wagon','Ford','1975',1020,'2l').
cars('V8 Super','Mitsibushi','2001',2010,'6l').

% display all cars made by that manufacturer enterd.
made:-
read(MAN),
write('All cars by '),
write(MAN),
!,
nl,
cars(X,MAN,_,_,_),
nl,
write(X),
fail.

% finds the least powerful car.
least:-
write('The least powerful car is '),
Z is 1,
N is 'car',
!,
nl,
cars(X,_,_,P,_),
P > Z, %If power of car is greater then previous car or 1 if this is the first car.
Z is P, %Set Z to P as temporary storage until the next car compares.
N is X, %If above passes, make the N var = to the last car checked.
nl,
fail,
write(N).
 
is" is for evaluation of arithmetic operations :
Code:
1 ?- X is 5 + 4 * 7.
X = 33

2 ?-
To assign un atom to a variable just write
N = car.
No need 'car' because of the lowercase c.

A string in SWI-Prolog (I don't know for other Prolog) is a list of codes :
Code:
2 ?- X = "car".
X = [99, 97, 114] 

3 ?-


 
I don't understand though its still not working, It gives no error now which is great but it does not seem to be proceeding with this line.

Z is P,

here is the code updated once again

% finds the least powerful car.
least:-
write('The least powerful car is '),
Z is 1,
N = car,
!,
nl,
cars(X,_,_,P,_),
P > Z, %If power of car is greater then previous car or 1 if this is the first car.
Z is P,
write(Z), %Set Z to P as temporary storage until the next car compares.
N is X, %If above passes, make the N var = to the last car checked.
nl,
fail,
write(N).
 
Your method smells "procedural", it can't work because, in Prolog you can't have in the same clause
Code:
Z is 1,
N = car,
....
Z is P,
...
N = X,
Think in words of "unification" not "affectation"
When, in a clause, Z is unified, you can't change its value.

What you want can be done very easily :
Code:
least:-
	write('The least powerful car is '),
	%% what you can do
	bagof((P, N), cars(N, _, _, P, _), L),
	msort(L, [(_, Name) | _]),
	write(Name).
I get a list of tuple (Power, Name), I order this list in ascending order and I write the first name.
 
It does not seem to be working however, it is only outputting the first car..

Also can you please explain bagof()

Wow I didn't realize there was those functions... Is their a good place to learn these function and that explains them for SWI-prolog.

Cheers, Kazzal
 
You wrote : "write('The least powerful car is ')"
To have all the names :
Code:
least:-
    write('The least powerful car is '),
    %% what you can do
    bagof((P, N), cars(N, _, _, P, _), L),
    msort(L, LS),
    maplist(write_name, LS).

write_name((_, Name)) :-
  writeln(Name).
If you use SWI-Prolog on Windows, you can read the online manual for explanations about predicates, else you google bagof SWI-Prolog.
 
I meant in the previous post, its not ordering them its only giving the list without it being the least powerful car.

Its only showing the first clause of cars regardless that it isn't the last powerful car....

 
Ok, when i run the program and try the least, it is only displaying the first one of these

cars('Camery','Hiyundi','1980',500,'2l').
cars('Ford XL','Hiyundi','1950',900,'5l').
cars('Tourino','Ford','1920',450,'3l').
cars('Wagon','Ford','1975',1020,'2l').
cars('V8 Super','Mitsibushi','2001',2010,'6l').

It always displays the Camery, even though it doesn't have the lowest power. If I move say the Ford-XL to the top, then it sais that one has the most power instead. It does not seem to be sorting them form lowest to highest just writing the first one of the cars..

Does that make sense?
 
Another way to sdo that is to use dynamic facts :
Code:
% search will fail but before failing
% it will look at all the cars.
% you must memorize the power in the database of Prolog
search :-
	cars(N, _, _, P,_),
	least(P1,_),
	(   P1 > P -> retract(least(_,_)),assert(least(P, N))),
	fail.

% finds the least powerful car.
least:-
	write('The least powerful car is '),
	retractall(least(_,_)),
	assert(least(1000000, _)),
	% search fails, so we must use \+ to succeed
	\+search,
	retract(least(_X,Y)),
	writeln(Y).
 
When I am running that code it is stil only displaying the first car clause.

So for this

cars('Camery','Hiyundi','1980',500,'2l').

I want the fourth paramater the 500 in this case to be compared against all the other cars power and then show the least powered car. So it would show when i run least with the below data:

cars('Camery','Hiyundi','1980',500,'2l').
cars('Ford XL','Hiyundi','1950',900,'5l').
cars('Tourino','Ford','1920',450,'3l').
cars('Wagon','Ford','1975',1020,'2l').
cars('V8 Super','Mitsibushi','2001',2010,'6l').

Output: The Car with the lowest power is Tourino.


So-

cars(TYPE,BRAND,DATE,POWER,ENGINE).

I want least to be able to show the car with the LOWEST power.

It is not doing this currently.
 
Working a charm now I replaced bagof with the function findall and it works great :)

Thankyou for all your help.
 
Hi
I found an another way of finding the least powerful car, and I think it's much more in the logic way of Prolog:
Code:
least:-
	write('The least powerful car is '),
	cars(X,_, _,P,_),
	\+((cars(_Y,_, _,P1,_),
	   P1 < P)), 
	write(X).
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top