Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog loop after results

So I wrote this predicate to find all possible subsets + permutations of a list. I get the correct output but for some reason the program keeps looping after giving me all the (correct) results.

What am I doing wrong?

% Gets all subsets of a list
aSubset([], []).
aSubset([E|Tail], [E|NTail]):- aSubset(Tail, NTail).
aSubset([_|Tail], NTail):- aSubset(Tail, NTail).

% gets all subsets and permutates them
allSubsets([],[]).
allSubsets(X, Res) :- permutation(S, Res), aSubset(X, S).

the results that I get for allSubsets([1,2,3], X) are:

4 ?- allSubsets([1,2,3], X).
X = [] ;
X = [1] ;
X = [2] ;
X = [3] ;
X = [1,2] ;
X = [1,3] ;
X = [2,3] ;
X = [2,1] ;
X = [3,1] ;
X = [3,2] ;
X = [1,2,3] ;
X = [1,3,2] ;
X = [2,1,3] ;
X = [2,3,1] ;
X = [3,1,2] ;
X = [3,2,1] ;
Action (h for help) ? abort
% Execution Aborted

where I have to abort the loop in the last two lines.

Thanks in advance.

like image 414
voluminat0 Avatar asked Mar 17 '23 15:03

voluminat0


1 Answers

Not only allSubset([1,2,3], X) loops, but also the much shorter allSubset([], X).

The following program fragment (failure-slice) loops already. So no need to look any further.

allSubsets([],[]) :- false.
allSubsets(X, Res) :-
   permutation(S, Res), false,
   aSubset(X, S).

To improve this, you need to change something in the visible part. Currently, only Arg2 (Res) can influence the goal permutation(S, Res), Arg1 (X) occurs only in the second goal, when it is already too late to influence (universal) termination of the first.

like image 82
false Avatar answered Mar 30 '23 09:03

false