【发布时间】:2012-04-01 17:12:46
【问题描述】:
我基本上是在尝试在 prolog 中创建 @
所以一些示例输入:
?- at_less(1.2,0)
yes
?-at_less(0,1.2)
no
?-at_less(f(1,2,a),f(1,2,b)).
yes
显然我不想使用 @
%atom_pr(+A1,+A2): A1 @< A2, where A1 and A2 are atoms.
atom_pr(L1,L2):-
atom_codes(L1,First), %atom codes for first
atom_codes(L2,Second),%atom codes for second
code_compare(First,Second). %compare the codes, return true or false
code_compare([HF|TF],[HS|TS]):-
( HF=HS ->
code_compare(TF,TS)
;
HF<HS ->
true
;
fail
).
code_compare([],X):-
true.
code_compare([],[]).
%(I understand this is probably not the most efficient way of going about this, but I'm %just beginning!)
我可以为所有常量做类似的事情,而不仅仅是原子吗?有没有类似 atom_codes/2 的命令?如果不是,我唯一能想到的就是把它分解成大量的 if -> else 语句,检查第一个是不是原子,第二个不是等等,但这似乎是一个也许有点乏味/糟糕的方法?
提前感谢您的帮助!
编辑:多亏了下面的帮助,我得到了一个正在运行的程序(至少据我所知)。我已经把它放在下面的代码中,以防其他人在这里徘徊。但是,我认为它的效率极低,因此还有很大的改进空间:)
%flat_pr(+F1, +F2): F1@<F2, where F1 and F2 are flat ground terms
flat_pr(F1,F2):-
( compound(F1) -> %these ifs here to check what type F1 and F2 are
( compound(F2) -> %comparing/succeeding/failing as appropriate
compound_compare(F1,F2) %(atom>integer>float>compound)
; % I believe these ifs could definitely be cut down though
( atom(F2) ->
true
;
( float(F2) ->
true
;
( integer(F2) ->
true
)
)
)
)
)
;
( atom(F1) ->
( compound(F2) ->
false
;
( atom(F2) ->
atom_pr(F1,F2)
;
( float(F2) ->
false
;
( integer(F2) ->
false
)
)
)
)
)
;
( float(F1) ->
( compound(F2) ->
false
;
( atom(F2) ->
true
;
( float(F2) ->
number_pr(F1,F2)
;
( integer(F2) ->
true
)
)
)
)
;
fail
)
;
( integer(F1) ->
( compound(F2) ->
false
;
( atom(F2) ->
true
;
( float(F2) ->
false
;
( integer(F2) ->
number_pr(F1,F2)
)
)
)
)
)
.
compound_compare(F1,F2):- %compares compounds (arity first)
functor(F1,N1,A1), %get arity
functor(F2,N2,A2),
( A1<A2 -> %compare arity
true
;
( A1>A2 ->
false
)
;
( A1=A2 -> %if arity the same
F1 =.. L1, %compound -> list
F2 =.. L2,
list_compare(L1,L2) %compare the lists
)
)
.
list_compare([],[]). %base case
list_compare([H|T],[H1|T1]):-
( flat_pr(H,H1) -> %if H@<H1
list_compare(T,T1) %compare Tails
;
false %else false
)
.
atom_pr(L1,L2):-
atom_codes(L1,First), %atom codes for first
atom_codes(L2,Second),%atom codes for second
code_compare(First,Second). %compare the codes, return true or false
number_pr(L1,L2):- %simple number comparison...straight forward
( L1=<L2 ->
true
;
fail
).
code_compare([HF|TF],[HS|TS]):- %just runs through atom codes
( HF=HS ->
code_compare(TF,TS)
;
HF<HS ->
true
;
fail
).
code_compare([],X):-
true.
code_compare([],[]).
不过,我很乐意看到改进这一点的方法!干杯
【问题讨论】: