論理的に純粋な状態を維持するのは簡単です。メタ述語
tcount/3
を具体化された型テスト述語number_t/2
(の略number_truth/2
) と組み合わせて使用します。
number_t(X,Truth) :- number(X), !, Truth = true.
number_t(X,Truth) :- nonvar(X), !, Truth = false.
number_t(X,true) :- freeze(X, number(X)).
number_t(X,false) :- freeze(X,\+number(X)).
OPが提案したクエリを実行しましょう:
?- tcount(number_t,[ 1 , 2 ,c,h, 4 ],N)。
N = 3. % が決定論的に成功する
これは単調であることに注意してください。変数バインディングを遅らせることは、常に論理的に健全です。検討:
?- tcount(number_t,[A,B,C,D,E],N), A=1 , B=2 , C=c, D=h, E=4 .
N = 3、A = 1、B = 2、C = c、D = h、E = 4 ; % は成功しますが、選択ポイントを残します
間違い。
最後に、次の非常に一般的なクエリの回答をいくつか見てみましょう。
?- tcount(number_t,[A,B,C],N).
N = 3, freeze(A, number(A)), freeze(B, number(B)), freeze(C, number(C)) ;
N = 2, freeze(A, number(A)), freeze(B, number(B)), freeze(C,\+number(C)) ;
N = 2, freeze(A, number(A)), freeze(B,\+number(B)), freeze(C, number(C)) ;
N = 1, freeze(A, number(A)), freeze(B,\+number(B)), freeze(C,\+number(C)) ;
N = 2, freeze(A,\+number(A)), freeze(B, number(B)), freeze(C, number(C)) ;
N = 1, freeze(A,\+number(A)), freeze(B, number(B)), freeze(C,\+number(C)) ;
N = 1, freeze(A,\+number(A)), freeze(B,\+number(B)), freeze(C, number(C)) ;
N = 0, freeze(A,\+number(A)), freeze(B,\+number(B)), freeze(C,\+number(C)).