I studing prolog and i got issues to resolve this exercise:
I need to create a a method that I call Relation(Variable, List of List)
EX:
list(a,b)
list(c,b)
list(c,h)
Return should be all the list that contains the variable Relation(c,X)
X= [[c,b],[c,h]]
Thank you in advance for your help
Here is the answer to the question :
check(_,[],X).
check(Var,[H|T],[H|X]):-member(Var,H),check(Var,T,X).
check(Var,[_|T],X):-check(Var,T,X).
Only that im not sure how to use the setof/3 procedure , since i need to load the predicates like this
list(a,b)
list(b,c)
list(c,t)
Related
I'm studying for an exam and got stuck on one of the prep questions:
Question:
The following Prolog-program is a meta-program. Explain why this
program is a meta-program and give the output to the three questions
to the program:
?- prove(moving_method(bird,M),N).
?- prove(moving_method(ross,M),N).
?- prove(moving_method(kim,M),N).
I'm trying to run the code(on swish.swi-prolog.org) but it only gives me this error message:
Sandbox restriction!
Could not derive which predicate may be called from
call(C)
prove(A,B)
prove(moving_method(bird,A),B)
The code we are given:
:- dynamic moving_method/2, is_a/2.
is_a(bird,animal).
is_a(ross,albatross).
is_a(kim,kiwi).
is_a(albatross,bird).
moving_method(bird,fly).
moving_method(kiwi,walk).
prove(Fact,l):-
Fact,!.
prove(Fact,X):-
Fact=..[Rel,A1,A2],
is_a(A1,SA),
NewFact=..[Rel,SA,A2],
prove(NewFact,X1),
X is X1 + 1.
The error message might be fairly straight forward but how do I fix it? And why is this a meta-program?
Thank you!
why is this a meta-program?
See: SWI-Prolog Meta-Call Predicates
Meta-call predicates are used to call terms constructed at run time.
In this case passing in the predicate to call, Fact, then running it as a goal.
I would like to ask if it is possible to assert a list instead of singular terms? For example I have tried the following:
assert(user_chosen_fruits([Grapes, Apples, Peaches])).
However, when I queried using user_chosen_fruits(X)., it returns me the following:
X = [_4872, _4878, _4884].
Am I missing out some output processing, or is my assertion simply wrong? I'm not sure if it is even possible to assert lists. Thanks for any help.
You are asserting a list of variables, hence the bindings you get when you call user_chosen_fruits/1. Try instead:
| ?- assertz(user_chosen_fruits(['Grapes', 'Apples', 'Peaches'])).
P.S. The assert/1 predicate is deprecated. Use instead the standard asserta/1 or assertz/1 predicates.
I'm pretty new to prolog and while learning it I stumbled upon a problem that I'm having. I basically have a few database facts. They are:
book(year(1937), title([of,mice,and,men]), rating_out_of_ten(9)).
book(year(2008), title([the,hunger,games]), rating_out_of_ten(8)).
I'm am trying to query the books that have the word "of" in the title. This is what I attempted:
book(year, title, rating_out_of_ten), member(of, title).
It returns false when I do this. Can someone please help. Thanks in advance.
So I'm new to the prolog too but I think I know the solution:
In your query you are actually using the wrong predicate, it should be book, instead of movie
The query should look like this:
book(X,title(Y),Z), member(of,Y)
Arguments have to be capitalized (they have to be variables), however to reach elements of the list you have to use list's name and then a variable, like this:
title(Y)
so you can use Y in the application of the member predicate.
Remember that variable names must start with a capital letter (or underscore). Also, are you really querying on movie when your facts are book?
You could try:
?- book(year(Y), title(T), rating_out_of_ten(R)), member(of, T).
I have a list of facts like
student(mary).
student(john).
etc, and also
course(math).
course(a).
course(b).
etc, and
took(john,math).
...
I have to say if a student can or can not graduate.
To graduate a student have to have all the courses taken. But how can I say this without write all term in the rule?
what I think was
can_graduate(X) :- took_all_courses(X).
but I dont know how to explain the rule took all courses without writing all courses. Can someone help me?
thanks.
took_all_courses(Student) :-
student(Student),
forall( course(C), took(Student,C) ).
Since this is Answer-Set Prolog and not Prolog, higher-order predicates such as forall are not available. What you want to do is count firstly the number of courses and secondly the number of courses the student has taken. How about using aggregates for this?
took_all_courses(Student) :-
student(S),
TotalCourses = #max{C:course(C)}, CoursesTaken = #max{C:took(S,C)},
TotalCourses == CoursesTaken.
I've not tested, but that should work, you might have to play around a bit with the syntax of the aggregates depending on the version of the grounder you are using, (e.g. see Clingo 3 vs 4).
I am trying to add one item to the end of a list in prolog, but it keeps on failing.
insertAtEnd(X,[ ],[X]).
insertAtEnd(X,[H|T],[H|Z]) :- insertAtEnd(X,T,Z).
letters([a,b,c]).
I do not understand why this below does not work.
insertAtEnd(d,letters(Stored),letters(Stored)).
I am also attempting to store this list in the variable Stored throughout, but I am not sure if the above is correct way to proceed.
you can use append
and put your item as second list
like this:
insertAtEnd(X,Y,Z) :- append(Y,[X],Z).
Prolog implements a relational computation model, and variables can only be instantiated, not assigned. Try
?- letters(Stored),
insertAtEnd(d, Stored, Updated),
write(Updated).