I got stuck to implement a logic. At some instance in my program I have a list say named as List.
The length of this List is variable and I don't know in advance. Now I have to pass this list in a functor to create a fact and I am unable to implement it. For eg:
if List is [first] then it should add the fact functor(first).
if List is [first,second] then it should add the fact functor(first,second).
if List is [first,second,third] then it should add the fact functor(first,second,third).
and so on...
I was trying by =.. but here I am unable to map that variable length constraint. For fixed length I am able to perform but I don't know in advance that how many elements will be there in list.
Any suggestions to implement this logic. Thanks.
I don't quite understand your problem with =.. but this worked for me:
assert_list(List) :-
Term =.. [my_functor|List],
assert(Term).
Note that I use my_functor instead of simply functor because functor/3 is a built-in predicate so you cannot assert ternary functor facts (functor(first, second, third)).
Calling it:
?- assert_list([first,second,third]).
true.
Checking that it works:
?- listing(my_functor).
:- dynamic user:my_functor/3.
user:my_functor(first, second, third).
true.
Note that technically, the different n-ary my_functor/n predicates are not the same predicates. You must use different queries in your program for each n. To circumvent this, you could simply assert the list as one and only argument of my_functor:
?- List = [first, second, third],
assert(my_functor(List)).
true.
?- listing(my_functor).
:- dynamic user:my_functor/3.
user:my_functor([first, second, third]).
true.
My SWI-Prolog version is 5.7.5.
Related
I want to write the rule unique(List) that checks if all elements in List are unique. I'm not allowed to use member, but I am allowed to use 'not'. Therefore I wrote the rule 'member' myself.
I wrote this:
member(Element, [Element|_]).
member(Element, [_|List]) :-
member(Element, List).
unique([H|T]) :-
not(in_list(H, T)),
unique(T).
The member-rule is working, it checks if Element is a member of List. But the unique- rule doesn't work. For the unique-rule is was expecting it would check if H was in T and then do the same for the Header of the Tail and so on. The 'not' makes from a false statement a True-output.
When I run this rule with query ?-unique([1,2,3,4,5]) it gives False. So what's my mistake?
I just discoverd the solutions a few moments later.
I added this above:
unique([]).
unique([_,[]]).
How to make this (or something similar) work in Prolog:
belief(john,red(apple)).
belief(peter,red(apple)).
X :- belief(john,X), belief(peter,X).
And get true. for the following query (while consulting above):-
?- red(apple).
First, it's useful to define a little helper to capture when all (relevant) persons believe something:
all_believe(Belief) :-
belief(john, Belief),
belief(peter, Belief).
Then you can define, for example:
red(Object) :-
all_believe(red(Object)).
green(Object) :-
all_believe(green(Object)).
And with your given set of beliefs you get:
?- red(apple).
true.
?- green(apple).
false.
This works. It requires you to define similar rules for any term that you want to use as a belief.
You can make this a bit shorter with macro definitions using term_expansion:
term_expansion(declare_belief(Belief),
Belief :- all_believe(Belief)).
This means that every top-level definition in your source code of the form declare_belief(Belief) should be treated as if you had written Belief :- all_believe(Belief) instead (with the variable Belief substituted appropriately).
So now you can just write this:
declare_belief(red(_)).
declare_belief(green(_)).
and it will be treated exactly like the longer definitions for red(Object) and red(Object) above. You will still have to write this kind of declaration for any term that you want to use as a possible belief.
Prolog does not allow the head of a rule to be just a variable. The head must be a nonvar term, whose functor (i.e., name and arity) identifies the predicate being defined. So, a possible solution would be something like this:
true_belief(X) :-
belief(john, X),
belief(peter, X).
belief(john, red(apple)).
belief(peter, red(apple)).
Examples:
?- true_belief(red(apple)).
true.
?- true_belief(X).
X = red(apple).
If a predicate has 2 arguments it can be called like this:
maplist(member(#),List_of_lists,New).
But what if I wanted to call it the other way around, iterating through a list of values to see if any of them belonged in a list I had already? How can i make it so that the elements of the list are not the last argument of the function but rather the first or the second or the third?
EDIT: That code above was an example not what I actually wanted.
pal_pos_esps(Letras, Pals_Possiveis, Espacos):-
maplist(palavras_possiveis_esp(Letras,Espacos,_,Pals_Possiveis),Espacos,Pals_Possiveis).
Espacos is a list of list: I want to call each of those lists as the third argument of the predicate. How can I do so?
How can i make it so that the elements of the list are not the last argument of the function but rather the first or the second or the third?
You could use a lambda construct. In SWi-Prolog there are either library(yall) or library(lambda) (available after you install it with ?- pack_install(lambda).).
Let's see a basic usage, allocating a matrix NxN, which requires swapping the arguments order of length/2.
With the autoloaded library(yall):
matrix(N,M) :- length(M,N), maplist([Row]>>length(Row,N),M).
Using library(lambda):
:- use_module(library(lambda)).
matrix(N,M) :- length(M,N), maplist(\Row^length(Row,N),M).
If I have a database such as:
number(0).
number(1).
number(2).
number(3).
number(4).
number(5).
number(6).
number(7).
number(8).
number(9).
and want to write a predicate numbers(L) that instantiates that L to a list of numbers. i.e.
numbers([A,B]).
should instantiate A and B to 10*10 different combinations of numbers, how would I do this. I want to show the recursion in the numbers(L) predicate, not use maplist.
Many thanks for your assistance
First, you should not use number/1 for your purposes, because it is a name of a built-in predicate. Rename number to num or some other name.
A rule that produces a pair of numbers is trivial:
numbers([A,B]) :- num(A), num(B).
Yes, that was really it!
Now you can print all of the combinations like this:
:- numbers([A,B]), write(A), write('-'), write(B), nl, fail.
Here is a demo on ideone.
I am new to learning prolog, and I want to know, if we have some procedure like
father("Nic","Adam").
and I want to write a function that it will add new value to this
father("Nic","Adam","something"..)
how can I do this? Using list? Or what?
Quick answer: You don't want to do that.
Longer answer: The father/2 predicate has a certain meaning, namely that for father(X,Y) X is the father of Y. A father/3 predicate is a different thing altogether. What do you want to achieve with that third argument? Normally, you use additional rules, which derive things from the father/2 predicate, or even resolve it to a father/3 argument.
The main question remains: what's the purpose of the third argument? If you want your resolution to work for certain specific 3rd arguments based on the existance of a corresponding father/2 predicate for example, you could do father(X, Y, 'something') :- father(X,Y) which will succeed if you have a corresponding father/2 fact.
PS: Do learn your terminology. In Prolog we don't speak of procedures and we don't write functions. Instead we have predicates, facts, rules, ...
PPS: I am not sure which Prolog implementation you are using, but you might want to use 'something' instead of "something". The latter usually creates a list of character codes, not a string:
?- X = 'some'.
X = some.
?- X = "some".
X = [115, 111, 109, 101].
Simply writing
father(nic, adam).
As a predicate already defines it. It is like stating a fact: you declare that father(nic, adam) is true, then you can execute the following with these expected results :
?- father(nic, adam).
Yes
?- father(nic, X).
X = adam