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!

making two new arguments 1

Status
Not open for further replies.

xristiana

Programmer
Oct 23, 2010
48
GR
Hi, I have written a small programm which shows a cd' s artist, released album, year, etc which is in this way:

cd(album(band(‘Coldplay’), name(‘Viva la Vida or Death and All His Friends’)), release(year(2008), uschart(1)), genre(‘Alternative rock’), price(new(25), used(18))).

This argument(cd) is repeated also for other arguments.
What I have to make is, the argument album_year(Album,Year) that succeeds when the Album has sold out the year 'Year'.
For example, ?- album_year(X,2003).
X = album('Coldplay', (‘Viva la Vida or Death and All His Friends’)
Of course in my programm it will show the 'band' and 'name' as well.
What I wrote is:
album_year(Album,Year) :- cd(Album(Band,Name),Release(Year1,Uschart), Genre, Price(New,Used)), Year is Year1.
but it doesn't work. :(
Also, we have to make the argument:
similar_album(Album1,Album2),
which succeeds when the two albums have the same genre. Thanks
 
OK, you need to match exactly the data about the Coldplay album with the skeleton you use in album_year. It's really hard for me to explain without giving you the exact solution which I don't want to right now, because it's simple enough for you to figure it out on your own :). It's hard to explain because the 'cd' fact is so complicated to handle textually, but I'll give you a simpler example and hope you can apply the knowledge on your 'cd' example.

Suppose you have the following fact:

Code:
cd('Coldplay', release(year(2008), uschart(1))).

Now if you want to find out all albums released in 2008, you would have to write a query that resembles the 'cd' fact up until the year information, which is what you need.

Code:
find_albums(Band, Year) :-
        cd(Band, release(year(Year), _)).

The variable Band stays for 'Coldplay', Year stays for 2008 and the other information regarding uschart does not concern us, so we use the anonymous variable '_'

?- find_albums(Band, 2008).
Band = 'Coldplay'

Or you can do it like this:

Code:
find_albums_1(Band, Year, USChart) :-
        cd(Band, release(Year, USChart)).

Then:

?- find_albums_1('Coldplay', Year, USChart).
Year = year(2008)
USChart = uschart(1)

So what you need to understand is that in this case, Year will be year(2008) and not just 2008. So if Year = year(2008) you can't do: Year1 is Year. But you could do that if Year = 2008.

And to find two similar albums that have the same uschart information you would write:

Code:
similar_album(A1, A2) :-
        A1 = cd(_, release(_, USChart1)),
        A2 = cd(_, release(_, USChart2)),
        USChart1 = USChart2.

See, the band names and the release years don't matter (anonymous variable), but the uschart information matters (the two uscharts have to be equal).

Now I hope you can solve your own problem. Pay attention to the inner format of your 'cd' term so you can get the necessary information
 
So, if I get it, because the argument album year has the arity 2, I have to use the anonymous variable. So, my programm would be

album_year(Album,Year):-cd(Album(Band,Name),release(year(Year1,_), _, _(_,_)), Year is Year1.

Is that correct? I could act similarly to the next argument(they have to have similar genre):

similar_album(Album1,Album2):-
A1=cd(_(_,_),_(_,_),genre(Genre1),_(_,_)).
A2=cd(_(_,_),_(_,_),genre(Genre2),_(_,_)).
Genre1=Genre2

or A1 should look like this(and so would similarly A2):
A1=cd(_,_,genre(Genre1),_).
 
I tried it with the way I mentioned above, and it didn't work. It says syntax error operator expected,and when I insert the query, it says error: toplevel undefined procedure album_year/2. :(
 
Since '_' is a variable, you can't use it like this:

Code:
_(_, _)

... or otherwise you could use any other variable like that:

Code:
X(_, _)

This is not allowed. It's ok to put it like you wrote last:

Code:
A1=cd(_,_,genre(Genre1),_).

This way you don't care for the album identification data and for the release data and for the price data, but you are only interested in the genre.

Your mistake is that 'similar_album' takes Album1 and Album2 as parameters and in the body you use A1 and A2. What's the link between these 4 variables? Look at my code above and you will find A1 and A2 both as parameters and also in the body. Also, combine the 3 lines that make the body of similar_album using commas (logical AND) and not dots. Again, look closely at my code from above.
 
Thank you for your answer. I changed a little bit my programm to this. I am giving you two examples:

cd(album(‘Coldplay’, ‘Viva la Vida or Death and All His Friends’), release(2008, 1), genre(‘Alternative rock’), price(25,18)).

cd(album(‘Lady Gaga’, ‘The Fame’), release(2008, 2), genre(‘Pop dance’), price(24, 17)).

However, the first argument (album_year) doesn't work and I did it as you said. Here it is:
album_year(Album,Year) :- cd(Album(Band,Name),release(Year1,_), _, _), Year is Year1.

Can you give me your lights?

I'll try the second argument as you said(similar_album).
However, there are other mistakes I'm facing, like when I put more parenthesis on the right, it is right, and when I put the same number, it's wrong. With the old programm, but I want to learn. Also, it says operation expected in the argument cd.What is wrong with these??? I can't figure out.
 
The correct version would be:

Code:
album_year(Album,Year) :-
    cd(Album, release(Year1,_), _, _),
    Year is Year1.

You see, you put Album(Band, Name) as the first argument of 'cd'. Either you use a single variable (Album) for the entire term like I did in the example above, or you can use a matching term like this: album(Band Name) ... but with album written in lowercase. Watch the two cd's that you defined (Coldplay and Lady Gaga) and you will see the first parameter has the form album(Band, Name) ... not Album(Band, Name) ... you have to match it exactly in your queries
 
It says:
ERROR: album_year/2: Undefined procedure: cd/4
ERROR: However, there are definitions for:
ERROR: cd/0

Perhaps there is a problem with the operators expected as it says. Can you see any mistake in the definition of cd? Perhaps because I am writing it first to a word document?

And the similar argument doesn't work either. It produces the answer false (what kind of answer is that? I only know yes or no in prolog) whatever I put, whether it is right or wrong.
 
Please show the whole program and the Prolog query that led to that erroneous output.
 
false = no and true = yes ... earlier versions of SWI-Prolog answered yes/no while more recent versions answer true/false
 
Ok, the whole programm is this:
cd(album(‘Coldplay’, ‘Viva la Vida or Death and All His Friends’), release(2008, 1), genre(‘Alternative rock’), price(25,18)).
cd(album(‘Lady Gaga’, ‘The Fame’), release(2008, 2), genre( ‘Pop dance’), price(24, 17)).
cd(album(‘Black Eyed Peas’, ‘Elephunk’), release(2003, 14),genre( ‘Hip hop’), price(24, 15)).
cd(album(‘Barbara Streisand’, ‘The Concert’), release(1994,10), genre(‘Traditional pop’), price(32, 23).
cd(album(‘The Cranberries’, ‘Everybody Else Is Doing It, So Why Can t We?’), release(1993, 18),genre( ‘Alternative rock’), price(28, 18)).
cd(album(‘U2’,‘The Joshua Tree’), release(1987, 1), genre(‘Rock’), price(25, 15)).
cd(album(‘Michael Jackson’, ‘Thriller’), release(1982, 1),genre( ‘Pop’), price(22, 16)).
cd(album(‘AC/DC’, ‘Back in Black’), release(1980, 4), genre(‘Hard rock’), price(20, 13)).
album_year(Album,Year) :- cd(Album, release(Year1,_), _, _), Year is Year1.
similar_album(Album1,Album2) :- Album1=cd(_,_,genre(Genre1),_), Album2= cd(_,_,genre(Genre2),_), Genre1=Genre2.
 
OK, your fourth 'cd' clause needs one more parenthesis at the end, before the final dot. It should end:

Code:
 ... price(32, 23)).

Then everything should work fine for album_year.

For similar_album the mistake is mine and I'm sorry, I wrote without actually testing in Prolog and I made a beginner mistake :(. Try this:

Code:
similar_album(Album1, Album2) :-
    cd(Album1, _, genre(Genre1), _),
    cd(Album2, _, genre(Genre2), _),
    Album1 \= Album2,
    Genre1 = Genre2.
 
The \= operator means 'different'. Without it, you will get that each album is similar to itself also, which is obvious but undesirable.
 
Thank you very much, but I tried this question of two albums which have the same genre (Alternative rock):
?- similar_album('Viva la Vida or Death and All His Friends','Everybody Else Is Doing It, So Why Can t We?').
false.
And it said false:S
 
No ... An album is a complex term like this:

album(Band, Name)

Just the band or just the name of the album won't do it, this is how we defined 'similar_album', to match both band name and album name.

Ask this to Prolog:

?- similar_album(X, Y).

If you want only the album name to be considered, then you must modify 'similar_album' like this:

Code:
similar_album(Album1, Album2) :-
    cd(album(_, Album1), _, genre(Genre1), _),
    cd(album(_, Album2), _, genre(Genre2), _),
    Album1 \= Album2,
    Genre1 = Genre2.
 
Thank you very very much, now it is running, you are so nice! I'll give you another star :) I'll try to figure out myself why the previous one was wrong. Ok, bye:)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top