how to use maplist and predicates - prolog

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).

Related

Prolog instantiating variable to a list

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.

swi-prolog won't answer query

I'm trying to write a query that will make sure an element is present in a list of lists, I tried this implementation:
membernested(E,[H|T]):-member(E,H).
membernested(E,[H|T]):-membernested(E,[T]).
but Prolog won't answer the query, any thoughts?
Change you second clause to:
membernested(E,[H|T]) :- membernested(E,T).
The tail of the list [H|T] is T, not [T]. There's no need to enclose it in another list.

prolog expanding predicate to iterate for multiple results, combining / resolving result sets

I have a predicate "lookupOptions" which returns one by one some lists (Menus).
I'm trying to get it to satisfy the case of multiple inputs. I can return a single set of options as follows, by reading the head of the "list_places" list.
find_options(Restaurant,Town,Menu) :- lookupOptions(Restaurant,H,Menu), list_places(Town,[H|T])
But, I'm not able to get it to iterate.
I have tried a lot of things, these were my best efforts so far.
a) standard enough iteration, but it wont resolve ...
doStuff(X,[],_).
doStuff(Restaurant,[H|T],_):- lookupOptions(Resturant,H,_), doStuff(Restaurant,T,_).
find_options(Restaurant,Town,Menu) :- doStuff(Restaurant,[H|T],Menu), list_places(Town,[H|T]).
b) expanding the goal predicate ...
find_options(_,Town,[H|T],_)
find_options(Restaurant,Town,Menu) :- find_options(Restaurant,Town,[],Menu).
find_options(Restaurant,Town,X,Menu) :- list_places(Town,X).
find_options(Restaurant,Town,[H|T],Menu) :- lookupOptions(Restaurant,[H],Menu), find_options(Restaurant,Town,T,Menu).
Would either of these work ? if the pattern was written correctly. Or if there was an appropriate cut put in place?
Any help most appreciated ...
It's no clear on what you want iterate. Prolog uses backtracking to examine all alternatives, then you should start backtracking if you are after some alternative, or use the all solutions family.
Now I think you want simply declare there could be more find_options(Restaurant,Town,Menu). Then try replacing the head match [H|T] with this:
find_options(Restaurant,Town,Menu) :-
lookupOptions(Restaurant,H,Menu),
list_places(Town, Places),
member(H, Places).
BTW T is a singleton in your original rule. This could be a hint for the need of generalize it.

Convert list into functor parameter

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.

In Prolog, how can I check for N of elements in list A in list B?

I have these two lists =
fruits([banana, apple, mangoes, pears]).
foodILike([hamburgers, banana, shakes, fries]).
I want to write a prolog predicate that will return true as soon as it sees 1 items in the foodsILike list in the fruits list. How can I go about doing so?
First, for the plain answer:
fruitsILike(F) :-
fruits(Fs)
member(F, Fs),
foodILike(Ls),
member(F, Ls).
You could avoid the membership check by flattening the fruits and foods lists:
fruit(banana).
fruit(apple).
...
foodILike(hamburger).
foodILike(banana).
...
fruitsILike(F) :-
fruit(F),
foodILike(F).
That said, you seem to try and solve problems in Prolog using imperative idioms, and that won't work. First, predicates do not return anything. When calling a predicate, Prolog unifies its arguments with valid values according to the facts and rules in the program. Therefore, the "returned value" are the assignments to unbound variables. Second, Prolog does not do something "as soon as". It iterates over all possible solutions. You get the first solution, then the second solution, and so on.
member can 1) individually generate all the members of a given list and/or 2) give a yes/no answer as to whether a particular element is in a particular list. I believe you want to use the first form on fruits to generate each of the elements of fruit, and the second form on foodILike to see if any of those is present.

Resources