简体   繁体   中英

Prolog facts of lists and a recursion predicate to accept permutations of lists

I have facts that accept certain lists. These lists are sorted.

acceptedList([1,2,3]).
acceptedList([4,5,6]).
acceptedList([7,8,9]).

Now, I would like to accept any permutation of the accepted lists as well. To do this, I would like to sort the input list and match it against the above facts.

I can solve this problem using a predicate whose name is not acceptedList , but I was wondering if this could be done in a recursive way.

Here is what I thought:

acceptedList(List) :-
    sort(List,SortedList),    % Sort the list to match against the facts.
    acceptedList(SortedList). % Match against the facts.

My idea is that this predicate should accept input lists such as [3,2,1] . However, this seems to go in an infinite loop, and with my lackluster prolog knowledge, I need some help understanding why and whether it's possible to solve this problem using acceptedList facts and a predicate whose name is the same.

Prolog has a library lists with a predicate permutation/2 that generates all permutations for a given list.

So wen can write:

acceptedList(Lb) :-
    acceptedList(La),
    permutation(La,Lb).

But now we have a problem: this predicate will keep generating lists. Since after it has enumerated the facts it will fire the predicate defined above, and this will again enumerate permutations, so we will then yield permutations of permutations, permutations of permutations of permutations, etc. This is probably not what we want.

The solution to this, is to split the facts from the predicate. So we can rewrite acceptedList/1 to acceptedListFact/1 :

acceptedList([1,2,3]).
acceptedList([4,5,6]).
acceptedList([7,8,9]).

acceptedList(Lb) :-
    acceptedList(La),
    permutation(La,Lb).

and we thus unify La with a list that is stated as a fact.

Now we obtain the following acceptedList/2 s:

?- acceptedList(L).
L = [1, 2, 3] ;
L = [1, 3, 2] ;
L = [2, 1, 3] ;
L = [2, 3, 1] ;
L = [3, 1, 2] ;
L = [3, 2, 1] ;
L = [4, 5, 6] ;
L = [4, 6, 5] ;
L = [5, 4, 6] ;
L = [5, 6, 4] ;
L = [6, 4, 5] ;
L = [6, 5, 4] ;
L = [7, 8, 9] ;
L = [7, 9, 8] ;
L = [8, 7, 9] ;
L = [8, 9, 7] ;
L = [9, 7, 8] ;
L = [9, 8, 7] ;
false.

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