简体   繁体   中英

defining a list as a rule and then getting the first element in Prolog

If not very familiar with Prolog, but we're using the programming language as an extent for another developed very unknown programming language. and my problem is the following. I am well aware of the fact that i can write in the Prolog query

([Head|Tail]) = ([a,b,c]).

and this will result in me getting

Head = a, Tail = b,c. 

However, this is not quite what I need. I am writing a bot which receives from the program a list. the list is basically something the bot has to walk over and find every element of the list in the program, call it an environment. Now my problem is the following:

I don't seem to be able to define some rules for how to get the first element of that list. Ive been trying all sorts of things. at first the statement :

parameterList([a,b,c,d].

nextElement(X) :- parameterList(Z), member(Z,X).

doesn't seem to work. Why is this not working? and I'll ask the next in advance as well since i haven't been able to figure out either. from the environment i get a parameter indexOfNextElement(B). this returns a value of which element of the list i need to retrieve. Of course it starts at 0, and once this one has been delivered by the bot, the index goes up (this goes automatically).

Again i am very new to Prolog, so there's a good chance I am doing all of the syntaxes wrong, but it would be amazing to help me figure out a way to do it

The way you are placing the arguments in member/2 [a,b,c,d] is the member in the list Z . Hence when querying it you get the variable X substituted by lists:

   ?- nextElement(X).
X = [[a,b,c,d]|_A] ? ;
X = [_A,[a,b,c,d]|_B] ? ;
...

If you flip the arguments:

nextelement(X) :-
   parameterList(Z),
   member(X,Z).

The result is what I think you want:

   ?- nextelement(X).
X = a ? ;
X = b ? ;
X = c ? ;
X = d ? ;
no

As for getting the element at the nth position: this is basically a relation between a list an index and the element at that index:

:- use_module(library(clpfd)).

list_nth_element(L,N,E) :-
   list_nth_element_(L,N,E,0).         % the first index is 0

list_nth_element_([H|_T],N,H,N).       % element at index N
list_nth_element_([_H|T],N,E,Pos0) :-
   N #> Pos0,                          % position differs from index
   Pos1 #= Pos0 + 1,                   
   list_nth_element_(T,N,E,Pos1).      % E must be in the tail

You can query this different ways. Which elements are at what indices?:

   ?- list_nth_element([a,b,c,d],N,E).
E = a,
N = 0 ? ;
E = b,
N = 1 ? ;
E = c,
N = 2 ? ;
E = d,
N = 3 ? ;
no

Which element is at index 1?:

   ?- list_nth_element([a,b,c,d],1,E).
E = b ? ;
no

At which position is element c ?:

   ?- list_nth_element([a,b,c,d],N,c).
N = 2 ? ;
no

In general, if you want to do something with all elements of the list, you can follow such a pattern:

predicatename([],...).
predicatename([H|T], ...) :-
    % do something with H here
    predicatename(T,...).

Note the ... in the head of the rules and the recursive goal. This is where you place the additional arguments of your relation (see list_nth_Element/3 above). Depending on what you want to query, you leave the according argument as a variable and Prolog will substitute that variable with solutions to the relation, one at a time (see example queries above).

Concerning your comment: The queries above are just some examples of how you can use list_nth_element/3. Of course you can also use it as a goal in your robot predicate:

robotpredicatename(...) :-
   ...
   % you get the list somewhere here
   ...
   list_nth_element(L,N,E),
   ...

Somewhere before the goal list_nth_element/3 your predicate gets the list of interest and binds it to a variable, say L . After the list is available you can use list_nth_element/3 and L to get the element at the desired position. Or you can use the pattern above to write a predicate instead of list_nth_element/3 that does something with every element of the list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM