Types Prolog术语的测试类型:轻微问题
下面是一些测试SWI 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)
% 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).
如果我们运行goalrt
,我们会得到以下结果(格式不太好):
这些测试通过:
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
标记仍然很奇怪。