Writing predicates in prolog, data search - prolog

Write the predicate, reach(Departure, Arrivals) to find all points you can get into from the Departure point.
We have this facts:
trip(Id, From, To, Price)
Id — flight number
From — departure point
To — Point of arrival
Price — price
trip(01, kuiv, odessa, 1500).
trip(02, kuiv, lviv, 700).
trip(03, uzhorod, krum, 6000).
trip(04, vunohradiv, odessa, 2540).
trip(05, ternopil, kuiv, 3800).
trip(06, zaporizhya, donetsk, 900).
trip(07, ternopil, mariupol, 7500).
For example
?- reach(kuiv([odessa, lviv])).
kuiv - we enter
odessa, lviv - this is the result

reach(Departure, Arrivals):-
trip(_, From, To, _)
I only know that this is how you need to start, maybe someone more knowledgeable will help you

Related

Prolog Recursion | using multiple predicates to calculate sum

could someone tell me how do I solve the below question:
people_in_capitals(N): N is the total number of people living in capital cities of the world.
"Useful predicates:
country(Name, ID, Capital, CapitalProvince, Size, Population)
city(Name, Country ID, Province, Population, Lat, Lon, Elevation)."
I can use "findall" function to get and store the capitals in List, however, how do I use items in the list to find the population from the predicate city?
Show your code so far!
Also, write a predicate that iterates over the list (as described here: https://www.doc.gold.ac.uk/~mas02gw/prolog_tutorial/prologpages/lists.html) and sums the city population into the target value.

Prolog, strange answer of setof

I'm using the online compiler https://swish.swi-prolog.org/
Given the next facts:
frontier(spain,france).
frontier(spain,portugal).
frontier(portugal,spain).
frontier(france,spain).
frontier(france,italy).
frontier(france,germany).
frontier(france,belgium).
frontier(france,swiztland).
frontier(belgium,netherlands).
frontier(belgium,france).
frontier(belgium,germany).
frontier(netherlands,germany).
frontier(netherlands,belgium).
frontier(germany,netherlands).
frontier(germany,belgium).
frontier(germany,france).
frontier(germany,austria).
frontier(germany,swiztland).
frontier(austria,germany).
frontier(austria,swiztland).
frontier(austria,italy).
frontier(swiztland,austria).
frontier(swiztland,france).
frontier(swiztland,germany).
frontier(swiztland,italy).
frontier(italy,france).
frontier(italy,swiztland).
frontier(italy,austria).
I would like to obtain all of the countries but without obtain repeated ones.
Thus, I use a setof predicate, which avoids the repeated, like this:
setof(Country, (frontier(Country,_)), Countries).
The problem is that, when I executed the query, I obtained some iterations:
[germany, italy, swiztland]
[france, germany, netherlands]
[belgium, germany, italy, spain, swiztland],
[austria, belgium, france, netherlands, swiztland]
[austria, france, swiztland]
[belgium, germany]
[spain]
[france, portugal]
[austria, france, germany, italy]
I don't understand why, I was expected that the list Countries return me the list of all the countries without repeated ones and sorted, that's why I use the anonymus variable in the second argument of the predicate frontier, because I don't care about the second argument, only I want the first argument without repeated ones.
Any help?

Issue running query in prolog with list and predicate

Currently trying to create a library recommendation system in prolog for a college assignment and being quite new to prolog I'm quite lost and was wondering if I could have some of this explained to me in fine detail.
Here are my facts and rules currently:
book(after_dark, haruki_murakami,fiction,182).
book(python, charlie, revision, 560).
book(nt_bible, sams, reference, 480).
book(monty_python, cleese, comedy, 300).
buildLibrary(Lib) :- findall(book(Title, Author, Genre, Size), book(Title, Author,
Genre, Size), Lib).
holiday(B,L) :- //this should take the list formed in buildLibrary along with a variable that represents a book
//and is true if and only if its genre is comedy or fiction and less than 400 pages
Expected input:
buildLibrary(L)
holidays(book(after_dark,haruki_murakami,fiction,182),L)
Ideally this should return true as it meets the requirements outlined
How do I go about setting the rule for holiday? Once I know how to do this I feel like I can get it working, I've tried multiple things and they've all returned errors in SWL prolog, once again thanks for any help!
If I correctly understand your implementation then you could do something like:
holiday(B,L) :- buildLibrary(Lib), check(L,B).
check(book(X, Y, Genre, Size),[book(X, Y, Genre, Size)|_]):-
(Genre = comedy ;Genre = fiction), Size < 400.
check(B,[book(_, _, Genre, Size)|T]):-
dif(Genre,comedy),dif(Genre,fiction), check(B,T).

Prolog return date and event associated with it

So hello guys, i have been working on this question for hours, but i can solve it, if you guys can give me hints that would be great!
The problem is long but i believe from what I can see that the solution won't be more than 5 lines.
So I'm given a bunch of Data, lets say:
day(1,1, 'New Year')
day(2,1, 'The day after the new year')
day(23,1, 'The day i will finally understand this language :)')
day(14,2, 'Valentin's day')
day(16,2, 'Family day')
day(22,2, 'hein.. dont now lol')
So the first number is the day, second month and third event, and
so on for the other months. each month also have a number a days:
nday(1,31).
nday(2,28).
nday(3,31).
nday(4,30).
nday(5,31).
If i enter DayofTheMonth(1,L), such that L is a List and 1 January,
i should return a list with all the days in that month and the events as well .
In this case it should be: [(1,'New year', (2,'The day after the new year'),
(23, 'The day i will finally understand this language :)')]. this is what i did: (i don't even know the basic case smh) I'm so sorry i know
this solution is wrong it doesn't even handle days that don't have event,
but i just don't know where to go, i just feed a feedback or something
dayoftheMonth(X, L):- nday(X,Answer),
dayMonth(X, Answer, L).
dayMonth(X,Y,[_|B]):-
X=<Y,
day(Day, X, Event),
W is Day + 1,
dayMonth(X,W,[(Day,Event)|B]).
You can use the predicate findall/3 for that. The predicate has three arguments:
The template, the format of the output
The goal, the predicate you call that should be matched
The bag, the returning list of predicates.
So dayofTheMonth simply reads:
dayofTheMonth(Month,List) :-
findall((Day,Event),day(Month,Day,Event),List).
If you want to solve it without a findall, you can solve it by iterating over all the days until the number of days. The basecase is thus when the day has passed the number of days of the month.
dayofTheMonth(Month,Day,[]) :-
nday(Month,Threshold),
Day > Threshold,
!.
The inductive case always looks if there is an event planned that day, if so, you put it as head of the list and append it with the events on the next day, if there is no such event, the resulting list is the list of the next days. So:
dayofTheMonth(Month,Day,[(Day,Event)|T]) :-
day(Day,Month,Event),
!,
Day1 is Day+1,
dayofTheMonth(Month,Day1,T).
dayofTheMonth(Month,Day,T) :-
Day1 is Day+1,
dayofTheMonth(Month,Day1,T).
Finally you only need to link the predicate dayOfTheMonth/2 with dayOfTheMonth/3 by starting - evidently - by day 1.
dayofTheMonth(Month,Events) :-
dayofTheMonth(Month,1,Events).
So the full code reads:
day(1,1, 'New Year').
day(2,1, 'The day after the new year').
day(23,1, 'The day i will finally understand this language :)').
day(14,2, 'Valentins day').
day(16,2, 'Family day').
day(22,2, 'hein.. dont now lol').
nday(1,31).
nday(2,28).
nday(3,31).
nday(4,30).
nday(5,31).
dayofTheMonth(Month,Day,[]) :-
nday(Month,Threshold),
Day > Threshold,
!.
dayofTheMonth(Month,Day,[(Day,Event)|T]) :-
day(Day,Month,Event),
!,
Day1 is Day+1,
dayofTheMonth(Month,Day1,T).
dayofTheMonth(Month,Day,T) :-
Day1 is Day+1,
dayofTheMonth(Month,Day1,T).
dayofTheMonth(Month,Events) :-
dayofTheMonth(Month,1,Events).

Unique elements in list (Prolog)

I'm implementing a variation on Einstein's Riddle and i'm having some trouble.
When trying to calculate the solution i try this:
solve(Street) :- Street = [_House1,_House2,_House3,_House4,_House5],
%hint one goes here
%hint two goes here
%etc.
I can then ask the solution by typing: solve(Street)
However this comes up as solution:
house(flower, food, pet, sport)
house(flower, food, pet, sport)
house(x , food, pet, sport)
house(flower, food, pet, sport)
house(x, flower, pet, sport)
As you can see there's 2 times x, the rest are all types of foods, flowers, pets and sports.
But every type is unique: if one person likes flower X, noone else can like X.
Now, the reason why my solution gives 2 x's is easy to see: we are given an amount of hints but in all the hints there are only mentioned 4 flowers. So Prolog doesn't know there is another flower, and just uses x twice, just because it's possible and fulfills all the other hints.
What i want to say is that all the types of foods and flowers etc. in Street are unique so he should leave some blank when he used all types already. 3 would look like: house(x , food, pet ,sport) and 5 would look like: house(_, flower, pet, sport).
I also tried adding this to the hints: (let's say "cactus" is one of the flowers not mentioned in the hints)
member(house(cactus,_,_,_), Street)
However then my program doesn't end...
A hint may look like this:
is_neighbour(house(_,_,_,football),house(_,_,fish,_), Street),
with : is_neighbour(A,B,List) giving true when A and B are next to each other in List.
The hint can be translated to: the person who loves football lives next to the person who has fish.
If any more info need to be provided i'm willing to elaborate. :)
To express that no flower is reported twice, and also to make sure that all flowers are bound, you can use the permutation/2 predicate: the list of all flowers should be a permutation of the list of specified flowers. This would read like [untested]
flowers([], []).
flowers([house(Flower,_,_,_)|Street], [Flower|Rest]) :- flowers(Street, Rest).
-- ...
flowers(Street, Flowers),
permutation(Flowers, [kaktus, tulpe, nelke, rose, fingerhut]),
Edit: for 10 flowers, using permutations is probably too slow. An alternative approach is
flower(kaktus).
flower(tulpe).
flower(nelke).
--...
flowers(Street,[F1,F2,F3,F4,F5,F6,F7,F8,F9,F10]),
flower(F1), flower(F2), F1\=F2,
flower(F3), F3\=F1, F3\=F2,
flower(F4), F4\=F1, F4\=F2, F4\=F3,
--...

Resources