i'am new in Prolog ,
i tried to write 5 lists and get the intersection between them ,
how i can achieve that, ** lists will be defined in file so it's not input from the user .
i see many resources they implement it with two lists and its work fine if i make list as query from user ...
but when i try to pre-defined lists in file it's not work.
simple description of part of my project to more clarify...
menus will display and user will select one from each of the season , weather condition , occasion...
lists will be about what clothes are appropriate
so for example user select "winter" season, "rainy" weather condition and "wedding"occasion
lists for each of them
rainy([take_umbrella, jacket,coat]).
winter([jacket,sweater,coat,take_umbrella]).
wedding ([take_umbrella,dress,jacket,coat]).
so the result form intersection will be take_umbrella ,jacket,coat
i hope my idea is clear, and thank you in advance:)
I try to predefined lists in file and it's work. Y your lists in file it's not work? I do not know. I fix your errors because your paste is not error free then it's work.
?- winter(Winter),
rainy(Rainy),
wedding(Wedding),
intersection(Winter, Rainy, Winter_and_Rainy),
intersection(Winter_and_Rainy, Wedding, Winter_and_Rainy_and_Wedding).
Winter = [jacket, sweater, coat, take_umbrella],
Rainy = [take_umbrella, jacket, coat],
Wedding = [take_umbrella, dress, jacket, coat],
Winter_and_Rainy = Winter_and_Rainy_and_Wedding, Winter_and_Rainy_and_Wedding = [jacket, coat, take_umbrella].
But if it's not know how many list maybe you make list and reduce.
?- % make some lists L1, L2, ..., Ln,
foldl(intersection, [L1, L2, ..., Ln-1], Ln, Intersection).
When is winter on a rainy wedding you reduce like:
?- winter(Winter), rainy(Rainy), wedding(Wedding),
foldl(intersection, [Winter, Rainy], Wedding, Intersection).
Winter = [jacket, sweater, coat, take_umbrella],
Rainy = Intersection, Intersection = [take_umbrella, jacket, coat],
Wedding = [take_umbrella, dress, jacket, coat].
You see order of element is change but is it problem? For me no problem.
Related
I am new to photon and I would like to know how I can create a list of elements in a list in order to print them on the terminal manually with a number in front of it.
lst = ["country", "inhabitants", "CO2-Emissions" ]
def make_header(lst):
first_column = []
for column_names in range(len(lst)):
first_column.append([])
for list in range(1):
column_names[first_column].append(list)
print(lst)
make_header(lst)
the output should be:
country
inhabitants
Co2 Emissions
Sadly I have no clue how to do that correctly. Could you give me a hint on that?
I want the columns displayed on the terminal as above.
I am not allowed to use maps, arrays, imports and other "fancy" and practical stuff so I approached for a nested loop.
Kind regards
Boris
I have predicates of students and sports they do, and I want to find out which students do a particular sport. I have this sofar, but i can only get results if I enter exact sports in a list , and my find predicate works only to find a sport in a list. I don't know how to put it together to use to find students that do 1 sport:
student('Quinton Tarentino', male, 12).
student('Tom Hanks', male, 9).
student('Ed Harris', male, 11).
does_sport('Quinton Tarentino', [soccer, hockey, cricket]).
does_sport('Tom Hanks', []).
does_sport('Ed Harris', [hockey, swimming]).
sports([soccer, hockey, swimming, cricket, netball]).
find(X) :- sports(L), member(X, L).
I tried things like:
?- does_sport(X, find(soccer, L)).
This just returns false. I know I need to link my sports list to the does_sports predicate but not sure how.
Any advice appreciated :)
To find out which students do a particular sport, you could define a predicate like so:
student_sport(St,Sp) :-
does_sport(St,L), % L is a list of sports student St does
member(Sp,L). % Sp is a member of list L
Then you can query for e.g. soccer, as you seem to intend in your question, like so:
?- student_sport(St,soccer).
St = 'Quintin Tarentino' ? ;
no
Hockey on the other hand yields two results:
?- student_sport(St,hockey).
St = 'Quintin Tarentino' ? ;
St = 'Ed Harris' ? ;
no
If you want to have a list of students doing hockey instead, you can use findall/3 like so:
?- findall(St,student_sport(St,hockey),L).
L = ['Quintin Tarentino','Ed Harris']
Or alternatively setof/3 to get a sorted list (without duplicates, in case you happened to have facts that contain any):
?- setof(St,student_sport(St,hockey),L).
L = ['Ed Harris','Quintin Tarentino']
Note that in some Prologs you might have to explicitly include a library to use member/2, e.g. in Yap: :- use_module(library(lists))., while others autoload it, e.g. SWI.
EDIT:
Concerning the issues you raised in your comment, let's maybe start with your observation that student_sport/2 produces the answers one at a time. That is intentional, as suggested by the predicate name that contains the word student in singular: It describes a relation between a student and a particular sport that very student practices. That's why I added the example queries with findall/3 and setof/3, to show ways how you can collect solutions in a list. You can easily define a predicate students_sport/2 that describes a relation between a particular sport and a list of all students who practice it:
students_sport(L,Sp) :-
setof(St,student_sport(St,Sp),L).
Concerning the sports-austere, you can choose an atom to denote that case, say none and then add an according rule to student_sport/2 like so:
student_sport(St,none) :- % <- rule for the sports-austere
does_sport(St,[]). % <- succeeds if the student does no sport
student_sport(St,Sp) :-
does_sport(St,L),
member(Sp,L).
This yields the following results:
?- student_sport(St,none).
St = 'Tom Hanks' ? ;
no
?- students_sport(St,none).
St = ['Tom Hanks']
?- students_sport(St,hockey).
St = ['Ed Harris','Quintin Tarentino']
?- students_sport(St,Sp).
Sp = cricket,
St = ['Quintin Tarentino'] ? ;
Sp = hockey,
St = ['Ed Harris','Quintin Tarentino'] ? ;
Sp = none,
St = ['Tom Hanks'] ? ;
Sp = soccer,
St = ['Quintin Tarentino'] ? ;
Sp = swimming,
St = ['Ed Harris']
And finally, concerning your assumption of your code being exactly as I wrote it: There is a similarity in structure, namely your predicate find/1 having a first goal (sports/1) involving a list and subsequently using member/2 to check for membership in that list. The second rule (or single rule before the edit) of student_sport/2 is also having a first goal (but a different one: does_sport/2) involving a list and subsequently using member/2 to check for membership in that list. Here the similarities end. The version I provided is not using sports/1 at all but rather the list of sports associated with a particular student in does_sport/2. Note that find/1 does not describe any connection to students whatsoever. Furthermore your query ?- does_sport(X, find(soccer, L)). indicates that you seem to expect some sort of return value. You can regard predicates as functions returning true or false but that is usually not very helpful when programming Prolog. The argument find(soccer,L) is not being called as you seem to expect, but literally passed as an argument. And since your facts do not include something along the lines of
does_sport(*SomeStudentHere*, find(soccer,L)).
your query fails.
I want to make a Prolog console application that shows venue name and rent for any event for a given(user input) location. So far I have been able to create a list of venues of a given(user input) location.
My code is given below.
listing(venue_location).
listing(venue_seating).
listing(venue_overhead).
venue_location(washington_party_hall1, washington).
venue_location(washington_party_hall2, washington).
venue_location(newyork_party_hall1, newyork).
venue_location(newyork_party_hall2, newyork).
venue_capacity(washington_party_hall1,300).
venue_capacity(washington_party_hall2,450).
venue_capacity(newyork_party_hall1, 340).
venue_capacity(newyork_party_hall2,500).
venue_rent(washington_party_hall1,1350).
venue_rent(washington_party_hall2,1200).
venue_rent(newyork_party_hall1,1500).
venue_rent(newyork_party_hall2,1000).
main:-
write("Enter a location"),nl,write("->"),
read(Loc),
findall(X,venue_location(X,Loc),Venues),
write(Venues).
This gives the following output:
Enter a location
->washington.
[washington_party_hall1,washington_party_hall2]
true.
Is there a way to use the venues list in venue_rent fact to get every list element's rent?
I want to display the name of these venues with their rents in this way:
washington_party_hall1 1350
washington_party_hall2 1200
You know that if you have a given venue, say Venue, you can get the rent from your facts:
?- Venue = washington_party_hall1, venue_rent(Venue, Rent).
Rent = 1350
If you want to get the rent for all of the venues in a list Venues, you can use member/2:
?- Venues = [washington_party_hall1,washington_party_hall2], member(Venue, Venues), venue_rent(Venue, Rent).
That's the basic query structure of what you want. Now if you want to write things to the terminal in a nice format, you can use a failure driven loop, which is a common way to display a list of items in a formatted fashion:
write_venue_rents(Venues) :-
member(Venue, Venues),
venue_rent(Venue, Rent),
write(Venue), write(' '), write(Rent), nl,
fail.
This doesn't give you aligned columns, but you get the idea. You can look up the formatting options and predicates for Prolog to format the output to your taste.
Another way is to use maplist/2:
% Write out the rent for a given venue
write_venue_rent(Venue) :-
venue_rent(Venue, Rent),
write(Venue), write(' '), write(Rent), nl.
% Write out the rent for a list of venues
write_venue_rents(Venues) :-
maplist(write_venue_rent, Venues).
I think the maplist/2 version is more elegant.
I am using SWI-PROLOG version 6.6.6
I want to print all the attributes of a particular predicate type.
I have a predicate called law with arity 2.
Some of the facts are
law(borrow,'To borrow Money on the credit of the United States').
law(commerce,'To regulate Commerce with foreign Nations, and among the several States, and with the Indian Tribes').
law(unifomity,'To establish an uniform Rule of Naturalization, and uniform Laws on the subject of Bankruptcies throughout the United States').
law(money,'To coin Money, regulate the Value thereof, and of foreign Coin, and fix the Standard of Weights and Measures').
law(punishment,'To provide for the Punishment of counterfeiting the Securities and current Coin of the United States').
law(establishment,'To establish Post Offices and post Roads').
law(exclusiverights,'To promote the Progress of Science and useful Arts, by securing for limited Times to Authors and Inventors the exclusive Right to their respective Writings and Discoveries').
law(court,'To constitute Tribunals inferior to the supreme Court').
etc.
Now I want to access a law by entering its type.
Such as,
power(X) :- law(X,Y), display('\nCongress has the power : '),display(Y).
powers(ALL) :- display('\nCongress has the powers : '), law(_,Y), display('\n'), display(Y).
This works perfectly. Now, I also want the user to know what all types of laws are there so that the user can enter it as a query to get the corresponding law.
ex power(money).
For this, I made a query to get all these keywords and add them to a list and display the list.
But the list that is finally printed is not complete.
powerList(L) :- findall(X,law(X,_), L).
I use this code to get the list.
But the output on the console is
L = [borrow, commerce, unifomity, money, punishment, establishment, exclusiverights, court, piracyfelony|...].
But, there are more law types even after piracyfelony and they are not getting printed to the console. How do I get them printed?
This is a feature of Prolog's toplevel loops that tries to keep the output short.
To find out how you might change it, ask which Prolog flags your Prolog supports that have a value being a list of at least two elements:
?- current_prolog_flag(F,Options), Options = [_,_|_].
F = debugger_print_options,
Options = [quoted(true), portray(true), max_depth(10), attributes(portray), spacing(next_argument)] ;
F = toplevel_print_options,
Options = [quoted(true), portray(true), max_depth(10), spacing(next_argument)] ;
F = argv,
Options = [swipl, '-f', none] ;
false.
Now modify it accordingly:
?- length(L,10).
L = [_G303, _G306, _G309, _G312, _G315, _G318, _G321, _G324, _G327|...].
?- set_prolog_flag(toplevel_print_options,[quoted(true), portray(true), max_depth(0), spacing(next_argument)]).
true.
?- length(L,10).
L = [_G303, _G306, _G309, _G312, _G315, _G318, _G321, _G324, _G327, _G330].
(In newer versions starting with SWI 7 there is another flag value, answer_write_options.)
I have trouble sorting two related but separate lists of tuple lists. One list is made up of tuple lists representing a blog post. The other list is made up of tuple lists representing a comment post.
The problem is when you would like the same order based on blog id value. The lists for blog posts is sorted via the date value. So you cannot just sort numerically via blog id for both blog and comment post. And you cannot just sort the comment post via date value because the date values of blog and related comment post may be different.
I am not sure how to approach the problem - at least not in an elegant way.
Should I use lists:nth and consequently get each tuple list and position value? Then I would get the value of blog id, Then I would search in the list for comment posts for that id. Get the value of that tuple list. Associate the value of that tuple list in a new list with the appropriate nth position value.
Should I use the lists:sort function?
Any suggestions with code samples much appreciated.
Here are two sample lists of tuple lists that can be used as a basis :
[[{<<"blog_id">>,<<"a2">>},
{<<"postDate">>,<<"2010-12-4T6:10:12">>},
{<<"message">>,<<"la di da bo di do">>}],
[{<<"blog_id">>,<<"b8">>},
{<<"postDate">>,<<"2009-12-3T10:09:33">>},
{<<"message">>,<<"that is cool">>}],
[{<<"blog_id">>,<<"a9">>},
{<<"postDate">>,<<"2009-12-2T18:12:29">>},
{<<"message">>,<<"i like san francisco">>}]]
[[{<<"comment_id">>,<<"n6">>},
{<<"related_blog_id">>,<<"b8">>},
{<<"postDate">>,<<"2010-12-5T15:10:12">>},
{<<"message">>,<<"yup really neat">>}],
[{<<"comment_id">>,<<"y2">>},
{<<"related_blog_id">>,<<"a9">>},
{<<"postDate">>,<<"2009-12-6T10:09:33">>},
{<<"message">>,<<"yes but rent is expensive">>}],
[{<<"comment_id">>,<<"x4">>},
{<<"related_blog_id">>,<<"a2">>},
{<<"postDate">>,<<"2009-12-5T16:12:29">>},
{<<"message">>,<<"sounds like a hit">>}]]
And the desired output is the following with first list unchanged and second list reordered :
[[{<<"blog_id">>,<<"a2">>},
{<<"postDate">>,<<"2010-12-4T6:10:12">>},
{<<"message">>,<<"la di da bo di do">>}],
[{<<"blog_id">>,<<"b8">>},
{<<"postDate">>,<<"2009-12-3T10:09:33">>},
{<<"message">>,<<"that is cool">>}],
[{<<"blog_id">>,<<"a9">>},
{<<"postDate">>,<<"2009-12-2T18:12:29">>},
{<<"message">>,<<"i like san francisco">>}]]
[ [{<<"comment_id">>,<<"x4">>},
{<<"related_blog_id">>,<<"a2">>},
{<<"postDate">>,<<"2009-12-5T16:12:29">>},
{<<"message">>,<<"sounds like a hit">>}],
[{<<"comment_id">>,<<"n6">>},
{<<"related_blog_id">>,<<"b8">>},
{<<"postDate">>,<<"2010-12-5T15:10:12">>},
{<<"message">>,<<"yup really neat">>}],
[{<<"comment_id">>,<<"y2">>},
{<<"related_blog_id">>,<<"a9">>},
{<<"postDate">>,<<"2009-12-6T10:09:33">>},
{<<"message">>,<<"yes but rent is expensive">>}]]
Ok, new try then :)
We have:
-module(foo).
-compile(export_all).
Basic module exports to test the thing
blogs() ->
[[{<<"blog_id">>,<<"a2">>},
{<<"postDate">>,<<"2010-12-4T6:10:12">>},
{<<"message">>,<<"la di da bo di do">>}],
[{<<"blog_id">>,<<"b8">>},
{<<"postDate">>,<<"2009-12-3T10:09:33">>},
{<<"message">>,<<"that is cool">>}],
[{<<"blog_id">>,<<"a9">>},
{<<"postDate">>,<<"2009-12-2T18:12:29">>},
{<<"message">>,<<"i like san francisco">>}]].
Your definition of blogs.
comments() ->
[[{<<"comment_id">>,<<"n6">>},
{<<"related_blog_id">>,<<"b8">>},
{<<"postDate">>,<<"2010-12-5T15:10:12">>},
{<<"message">>,<<"yup really neat">>}],
[{<<"comment_id">>,<<"y2">>},
{<<"related_blog_id">>,<<"a9">>},
{<<"postDate">>,<<"2009-12-6T10:09:33">>},
{<<"message">>,<<"yes but rent is expensive">>}],
[{<<"comment_id">>,<<"x4">>},
{<<"related_blog_id">>,<<"a2">>},
{<<"postDate">>,<<"2009-12-5T16:12:29">>},
{<<"message">>,<<"sounds like a hit">>}]].
Your definition of comments.
sorted_comments() ->
[[{<<"comment_id">>,<<"x4">>},
{<<"related_blog_id">>,<<"a2">>},
{<<"postDate">>,<<"2009-12-5T16:12:29">>},
{<<"message">>,<<"sounds like a hit">>}],
[{<<"comment_id">>,<<"n6">>},
{<<"related_blog_id">>,<<"b8">>},
{<<"postDate">>,<<"2010-12-5T15:10:12">>},
{<<"message">>,<<"yup really neat">>}],
[{<<"comment_id">>,<<"y2">>},
{<<"related_blog_id">>,<<"a9">>},
{<<"postDate">>,<<"2009-12-6T10:09:33">>},
{<<"message">>,<<"yes but rent is expensive">>}]].
Your definition of being sorted.
sort(Blogs, Comments) ->
%% Create list of blog id's
Bs = [proplists:get_value(<<"blog_id">>, B) || B <- Blogs],
Fetch all the blog_id values from the Blogs.
%% Create the numbering
DB = dict:from_list([Item || Item <- lists:zip(Bs,
lists:seq(1, length(Bs)))]),
Number the order the blogs occur in. Stuff these into a dict for fast lookup later.
%% Sorter function:
F = fun(I, J) ->
II = proplists:get_value(<<"related_blog_id">>,
I),
JJ = proplists:get_value(<<"related_blog_id">>,
J),
dict:fetch(II, DB) =< dict:fetch(JJ, DB)
end,
This function compares two Comments, I, J to each other based on their related blog_id.
{Blogs, lists:sort(F, Comments)}.
Return what we want to return.
sort_test() ->
{blogs(), sorted_comments()} == sort(blogs(), comments()).
Tester function.
2> c(foo).
{ok,foo}
3> foo:sort_test().
true