Оставайтесь логически чистыми и эффективными. Как? С помощью мета-предиката tpartition/4
и (#=<)/3
!
Во-первых, давайте определим (#=<)/3
, усовершенствованную версию (#=<)/2
, основанную
bool01_t/2
.
Для полноты картины давайте также определим (#<)/3
, (#>)/3
и (#>=)/3
!
#=<(X,Y,Truth) :- X #=< Y #<==> B, bool01_t(B,Truth).
#<( X,Y,Truth) :- X #< Y #<==> B, bool01_t(B,Truth).
#>( X,Y,Truth) :- X #> Y #<==> B, bool01_t(B,Truth).
#>=(X,Y,Truth) :- X #>= Y #<==> B, bool01_t(B,Truth).
Вот и все! Теперь давайте сделаем разделение, которое хотел ОП:
?- tpartition(#=<(0),[1,-2,3,4,-8,0],Ts,Fs).
Ts = [1,3,4,0], Fs = [-2,-8]. % succeeds deterministically
Это монотонное , поэтому мы получаем звуковые ответы даже при использовании общих, неосновных терминов:
?- tpartition(#=<(0),[A,B,C],Ts,Fs).
Ts = [ ], Fs = [A,B,C], A in inf.. -1, B in inf.. -1, C in inf.. -1 ;
Ts = [ C], Fs = [A,B ], A in inf.. -1, B in inf.. -1, C in 0..sup ;
Ts = [ B ], Fs = [A, C], A in inf.. -1, B in 0..sup, C in inf.. -1 ;
Ts = [ B,C], Fs = [A ], A in inf.. -1, B in 0..sup, C in 0..sup ;
Ts = [A ], Fs = [ B,C], A in 0..sup, B in inf.. -1, C in inf.. -1 ;
Ts = [A, C], Fs = [ B ], A in 0..sup, B in inf.. -1, C in 0..sup ;
Ts = [A,B ], Fs = [ C], A in 0..sup, B in 0..sup, C in inf.. -1 ;
Ts = [A,B,C], Fs = [ ], A in 0..sup, B in 0..sup, C in 0..sup .
Редактировать 2015-06-02
Что если мы использовали предикат библиотеки SWI-Prolog partition/4
в запросе выше?
?- partition(#=<(0),[A,B,C],Ts,Fs).
Ts = [A,B,C], Fs = [], A in 0..sup, B in 0..sup, C in 0..sup.
Мы бы потеряли 7 из 8 решений, потому что partition/4
не является монотонным!