Types Prolog术语的测试类型:轻微问题

Types Prolog术语的测试类型:轻微问题,types,prolog,swi-prolog,Types,Prolog,Swi Prolog,下面是一些测试SWI Prolog术语类型/元类型的代码: % var,nonvar are meta-question about the state of computation, not about the term % Note: X can be a variable (if it is fresh) or a nonvar (if it is set) % but x can ever only be a nonvar typeof(X, var)

下面是一些测试SWI Prolog术语类型/元类型的代码:

% var,nonvar are meta-question about the state of computation, not about the term
% Note: X can be a variable (if it is fresh) or a nonvar (if it is set)
%       but x can ever only be a nonvar

typeof(X, var)           :- var(X),!.     % if it's a variable, we don't look for any other match
typeof(X, nonvar)        :- nonvar(X).    % nonvar(X) is the complement of var(X)

typeof(X, int)           :- integer(X).   % is there a way to distinguish "machine ints" from "bigints"? 
typeof(X, float)         :- float(X).     % IEEE 754 floats; magnitude: always double (what if long doublr arrives?)
typeof(X, number)        :- number(X).    % rationals are not (yet) numbers
typeof(X, rational)      :- rational(X).  % covers "big decimals" too

typeof(X, atom)          :- atom(X).
typeof(X, atomic)        :- atomic(X).

typeof(X, string)        :- string(X).

typeof(X, blob(T))       :- blob(X,T).

typeof(X, compound(F,A)) :- compound(X), X =.. [F|Args], length(Args,A).

typeof(X, ground)        :- ground(X).

typeof(X, cyclic)        :- cyclic_term(X).

typeof(X, list(Len))     :- is_list(X),length(X,Len).    % being a "list" is specific nonlocal phenomenon

typeof(X, conj(Len))     :- nonvar(X),is_conjunction(X,Len).
typeof(X, disj(Len))     :- nonvar(X),is_disjunction(X,Len).

typeof((_A->_B) , impl).
typeof(:-_A     , directive).
typeof(_H:-_B   , clause).

is_conjunction((_,B),Len) :- is_conjunction(B,Lb),!,Len is Lb+1.
is_conjunction((_,_),1).

is_disjunction((_;B),Len) :- is_disjunction(B,Lb),!,Len is Lb+1.
is_disjunction((_;_),1).

%
% TEST CODE
%

:- begin_tests(type_inspection).

test('empty list')      :- is_this_right([]               , [atomic,ground,nonvar,blob(reserved_symbol),list(0)]).
test('an atom')         :- is_this_right(foo_the_atom     , [atom,atomic,ground,nonvar,blob(text)]).
test('a string')        :- is_this_right("foo_the_string" , [atomic,ground,nonvar,string]).
test('a variable')      :- is_this_right(_VAR             , [var]).
test('integer')         :- is_this_right(4377                 , [atomic,ground,int,nonvar,number,rational]).
test('big integer')     :- is_this_right(43759624750933342417 , [atomic,ground,int,nonvar,number,rational]).
test('decimal')         :- is_this_right(5600.556 , [atomic,float,ground,nonvar,number]).
test('float')           :- A is 2/6, is_this_right(A, [atomic,float,ground,nonvar,number]).
test('/ compound')      :- is_this_right(2/6, [ground,nonvar,compound('/',2)]).
test('float')           :- is_this_right(1.234    , [atomic,float,ground,nonvar,number]).
test('rational')        :- is_this_right(5r6      , [atomic,ground,nonvar,number,rational]).
test('rational')        :- R is 5 rdiv 6, is_this_right(R, [atomic,ground,nonvar,number,rational]).
test('cyclic compound') :- A = a(1,2,3,A), is_this_right(A, [cyclic,ground,nonvar,compound(a,4)]).

test('dict')            :- is_this_right(_{a:1,b:2}, [nonvar,compound(dict,5)]).
test('cyclic list')     :- A = [1,2,3|A], is_this_right(A, [cyclic,ground,nonvar,compound(['|'],2)]).
test('nonempty list')   :- is_this_right([1,2,3]          , [ground,nonvar,list(3),compound(['|'],2)]).

setify(A,B,As,Bs) :-      % A,B -> As,Bs
   list_to_ord_set(A,As), % A->As
   list_to_ord_set(B,Bs). % B->Bs

is_this_right(Value,Expected) :-
   setof(T,typeof(Value,T),Ts),
   verdict(Value,Expected,Ts).

verdict(Value,Expected,Got) :-   % V,E,G -> b?
   setify(Expected,Got,Eos,Gos),  
   (ord_seteq(Eos,Gos)
    -> format("For ~w we have: ~w\n",[Value,Gos])
    ;  (format("For ~w, expected ~w but got ~w\n",[Value,Eos,Gos]),fail)).

:- end_tests(type_inspection).


rt :- run_tests(type_inspection).
如果我们运行goal
rt
,我们会得到以下结果(格式不太好):

这些测试通过:

For [] we have: [atomic,ground,nonvar,blob(reserved_symbol),list(0)]
For foo_the_atom we have: [atom,atomic,ground,nonvar,blob(text)]
For foo_the_string we have: [atomic,ground,nonvar,string]
For _15852 we have: [var]
For 4377 we have: [atomic,ground,int,nonvar,number,rational]
For 43759624750933342417 we have: [atomic,ground,int,nonvar,number,rational]
For 5600.556 we have: [atomic,float,ground,nonvar,number]
For 0.3333333333333333 we have: [atomic,float,ground,nonvar,number]
For 2/6 we have: [ground,nonvar,compound(/,2)]
For 1.234 we have: [atomic,float,ground,nonvar,number]
For 5r6 we have: [atomic,ground,nonvar,number,rational]
For 5r6 we have: [atomic,ground,nonvar,number,rational]
For @(S_1,[S_1=a(1,2,3,S_1)]) we have: [cyclic,ground,nonvar,compound(a,4)]
但是
|
函子的复合项有一个问题。我必须使用什么符号才能通过测试

For _15714{a:1,b:2}, 
expected [nonvar,compound(dict,5)] 
but got [nonvar,compound(dict,5)]

For @(S_1,[S_1=[1,2,3|S_1]]), 
expected [cyclic,ground,nonvar,compound([|],2)] 
but got [cyclic,ground,nonvar,compound([|],2)]

For [1,2,3], expected [ground,nonvar,list(3),compound([|],2)]
but got [ground,nonvar,list(3),compound([|],2)]

还有,有没有办法区分“大整数”和“机器整数”(除了检查大小?

你应该用
~q
来写术语(即写引号),而不是
~w
。尝试:

verdict(Value,Expected,Got) :-   % V,E,G -> b?
   setify(Expected,Got,Eos,Gos),  
   (   ord_seteq(Eos,Gos)
   ->  format("For ~q we have: ~q\n",[Value,Gos])
   ;   format("For ~q, expected ~q but got ~q\n",[Value,Eos,Gos]),
       fail
   ).
否则,您可能会对结果的解释产生误导:

For _4414{a:1,b:2},
    expected [nonvar,compound(dict,5)]
    but got [nonvar,compound(C'dict',5)]
ERROR: user://1:68:
    test dict: failed

For @(S_1,[S_1=[1,2,3|S_1]]),
   expected [cyclic,ground,nonvar,compound(['|'],2)]
   but got [cyclic,ground,nonvar,compound('[|]',2)]
ERROR: user://1:69:
    test cyclic list: failed

For [1,2,3],
    expected [ground,nonvar,list(3),compound(['|'],2)]
    but got [ground,nonvar,list(3),compound('[|]',2)]
ERROR: user://1:70:
    test nonempty list: failed
请注意:

?- functor([1,2,3], Functor, Arity).
Functor = '[|]',
Arity = 2.

?- functor(key{a:1,b:2}, Functor, Arity).
Functor = C'dict',
Arity = 5.

为什么??SWI Prolog改变了传统的和标准的
'./2
列表函子,使其可以用于DICT。由于解析的方式,Dicts有一个奇怪的函子。

显然我最好用它来处理中的边缘情况,上面反映了SWI-Prolgo的特殊性或过程:(列表不使用cons单元格和
函子,常量
[]
指定一个特殊的非原子),还有致谢的保罗。但是
key{x:1,y:2,a:7}=>中的
C
背后的想法是什么呢。。L.L=[C'dict',key,7,a,1,x,2,y]。
?通过“[|]”引用“|”函子的规则是什么?@DavidTonhofer用更多的见解更新我的答案。哦,我明白了。函子实际上是(由)3个字符的原子“[|]”。分解:
[1]=。。L.-->L=['[]',1,[].
并重新组合
L=。。['[|]',1, []]. ---> L=[1]。
以及
L='[|]'(1,[])。-->L=[1]。
。但是,
C
标记仍然很奇怪。