Ich versuche, einige reine Prädikate aus früheren Stapelüberlauffragen zu kombinieren, um mein eigenes Prädikat zu erstellen.Kombinieren von reinen Prädikaten
Ich möchte eine Liste von cs geben (die zugeordnete Fakten haben -'ats 'mit ihnen) und einen' Merkmal'-Begriff, der einen Operator und einen Schwellenwert für ein 'at' hat. Ich möchte die Listen von cs partitionieren, wenn das c nicht das entsprechende "at" von dem "Feature" hat, wird es in die falsche Partition gehen, sonst wird der Operator das "at" für das "c" testen und die c ist angemessen.
Zum Beispiel:
?-cpgpartition_ts_fs_feature([c1,c2,c3],Ts,Fs,feature(at2,_,>=,10)).
Sollte ergeben:
Ts = [c3], %c3 has an at2 >= 10
Fs = [c1,c2]. %c1 has at2 <10 and c2 does not have an at2
Dies ist der Code, den ich habe:
:-use_module(library(clpfd)).
cpgpartition_ts_fs_feature([],[],[],_).
cpgpartition_ts_fs_feature([X|Xs0],Ts,Fs,Feature):-
Feature = feature(At,_,Op,FValue),
cpg_ats_i(X,AtList),
atom_concat(#,Op,Op2), %make clpfd operator
Test =..[Op2,AtValue3,FValue],
if_(memberd_t(attribute(At,AtValue3),AtList),
(
if_(call(Test), (Ts=[X|Ts0],Fs=Fs0),
( Ts =Ts0,Fs=[X|Fs0]))
)
,Fs=[X|Fs0]),
cpgpartition_ts_fs_feature(Xs0,Ts0,Fs0,Feature).
if_(If_1, Then_0, Else_0) :-
call(If_1, T),
( T == true -> call(Then_0)
; T == false -> call(Else_0)
; nonvar(T) -> throw(error(type_error(boolean,T),_))
; /* var(T) */ throw(error(instantiation_error,_))
).
bool01_t(1,true).
bool01_t(0,false).
=(X, Y, T) :-
( X == Y -> T = true
; X \= Y -> T = false
; T = true, X = Y
; T = false,
dif(X, Y) % ISO extension
% throw(error(instantiation_error,_)) % ISO strict
).
#=<(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).
list_memberd_t([] ,_,false).
list_memberd_t([Y|Ys],X,Truth) :-
if_(X=Y, Truth=true, list_memberd_t(Ys,X,Truth)).
list_memberd_truth(Xs,X,Truth) :- list_memberd_t(Xs,X,Truth).
memberd_t(X,Xs,Truth) :- list_memberd_t(Xs,X,Truth).
value_intvalue(attribute(_A,X),attribute(_A,Y)):-
AtValue2 is X *100, %Convert decimal number to integer.
Y is integer(AtValue2).
cpg_ats_i(C,AtList):-
cpg_ats(C,Ats),
maplist(value_intvalue,Ats,AtList).
cpg_ats(c1,[attribute(at1,0.5),attribute(at2,0.03)]).
cpg_ats(c2,[attribute(at1,0.02)]).
cpg_ats(c3,[attribute(at2,0.1),attribute(at3,0.04),attribute(at4,0.08)]).
Wenn die Testabfrage versucht, erhalte ich:
cpgpartition_ts_fs_feature([c1,c2,c3],Ts,Fs,feature(at2,_,>=,10)).
Fs = [c1, c2] ;
Fs = [c1, c2, c3] ;
Fs = [c1, c2] ;
Fs = [c1, c2, c3].
Und interessanterweise ändern sich die Ergebnisse, wenn die Reihenfolge der CLIST unterschiedlich ist.
?- cpgpartition_ts_fs_feature([c3,c1,c2],Ts,Fs,feature(at2,_,>=,10)).
Ts = [c3|_12950],
Fs = [c1, c2] ;
Ts = [c3|_12950],
Fs = [c1, c2] ;
Fs = [c3, c1, c2] ;
Fs = [c3, c1, c2].
Ich denke, das liegt daran, dass die folgende Abfrage liefert Ergebnisse mit dif/2
Zwängen, die für unangemessen erscheinen, was ich zu tun versuchen, nur ich die konkreten Lösungen wollen.
?- cpg_ats_i(C,Ats), if_(memberd_t(attribute(at2,AtValue),Ats),Q=true,Q=false).
C = c1,
Ats = [attribute(at1, 50), attribute(at2, 3)],
AtValue = 3,
Q = true ;
C = c1,
Ats = [attribute(at1, 50), attribute(at2, 3)],
Q = false,
dif(AtValue, 3) ;
C = c2,
Ats = [attribute(at1, 2)],
Q = false ;
C = c3,
Ats = [attribute(at2, 10), attribute(at3, 4), attribute(at4, 8)],
AtValue = 10,
Q = true ;
C = c3,
Ats = [attribute(at2, 10), attribute(at3, 4), attribute(at4, 8)],
Q = false,
dif(AtValue, 10).
Auch ist das Ziel für diesen Code auf einer großen Menge von Daten ausgeführt werden, die Liste der c Hunderttausende in der Länge und jeder c könnte 50k von ats haben sein, wie ich die Speicheranforderungen arbeiten können ? und ist ein anderer Ansatz mit unreinen Prädikaten, die wahrscheinlich weniger Speicher benötigen?
Auf den ersten Blick ersetzen "Test = .. [Op2, AtValue3, FValue], ..., Aufruf (Test)" durch 'Aufruf (Op2, AtValue3, FValue)' – false
Fertig. Aber es scheint keinen Unterschied zu machen ... – user27815