Binary 双向确定性二进制减量

Binary 双向确定性二进制减量,binary,prolog,Binary,Prolog,我想知道是否有可能在纯Prolog中单独实现一个双向和确定性的二进制减量器。运行示例包括模式(-,+)的和: 对于模式(+,-): 或者,任何模式都不应留下任何错误。但是强制的实现必须仅在纯Prolog中进行,因此没有cut、findall、var等等 我已经尝试了一个定义,如下dec(X,Y):-binary_plus([1],Y,X)。使用二进制加法器。但是它没有通过最后一个测试用例,因为我得到了dec([0,0,0,1],X)。X=[1,1,1];X=[1,1,1,0];错误。以下两个查询

我想知道是否有可能在纯Prolog中单独实现一个双向和确定性的二进制减量器。运行示例包括模式(-,+)的和:

对于模式(+,-):

或者,任何模式都不应留下任何错误。但是强制的实现必须仅在纯Prolog中进行,因此没有cut、findall、var等等


我已经尝试了一个定义,如下
dec(X,Y):-binary_plus([1],Y,X)。
使用二进制加法器。但是它没有通过最后一个测试用例,因为我得到了
dec([0,0,0,1],X)。X=[1,1,1];X=[1,1,1,0];错误。

以下两个查询测试确定性。他们没有成功。两者都可以无限地运行;并以给定的
N
失败。为了表示不终止,查询的前缀是
:/-&

:/-& length(Bs,N), dec(Bs, Ds1), dif(Ds1, Ds2), dec(Bs, Ds2).

:/-& length(Ds,N), dec(Bs1, Ds), dif(Bs1, Bs2), dec(Bs2, Ds).

dec([1|Bs],[0|Bs]) :-
   nil_or_ends_with_one(Bs).
dec([0|Bs],[1|Ds]) :-
   deci(Bs, Ds).

nil_or_ends_with_one([]).
nil_or_ends_with_one([E|Es]) :-
   ends_with_one(Es, E).

ends_with_one([], 1).
ends_with_one([E|Es], _) :-
   ends_with_one(Es, E).

deci([1],[]).
deci([1|Bs],[0|Bs]) :-
   Bs = [B|_],
   ends_with_one(Bs, B).
deci([0|Bs],[1|Ds]) :-
   deci(Bs, Ds).
解决方案仍然有点过于笼统,因为它接受

?- dec([1,non_digit,1],[0,non_digit,1]).

这很容易修复,但似乎不值得花费。

我得到了一个不同的解决方案,它不是针对Prolog,而是针对一个平面索引Prolog。到目前为止,所有4个测试用例都没有在Jekejeke Prolog中留下任何选择点,它具有完全平坦的索引。:-)

但是,完全扁平索引的缺点是在编码谓词时会增加额外的开销,以便将其转换为扁平形式。如二进制_plus/3示例所示,平面形式也很流行。但最好的可能是既有平坦的,也有深邃的,而后者以一种存在


deep dec/2版本,永远不会留下选择点。

最近被提示删除的相同内容:将问题视为一个问题。您需要定义确定性的含义。您的意思似乎是:不在特定的Prolog系统上留下选择点。你指的是哪一个?在链接的帖子中显示SWI和其他系统之间存在差异。@false我已经标记了您的评论。你在用无关紧要的废话骚扰我。这不是第一次了。确定性在数学中定义为确定性关系。选择点(CP)在WAM中定义为,包括省略CP的优化。关于CP,问题说的是“应该”,而不是“必须”。这个词或形容词“建议”是否意味着在特定情况下可能存在忽略特定项目的正当理由,但在选择不同的课程之前,必须理解并仔细权衡其全部含义。在SWI Prolog中,这几乎没有留下选择点。可能是因为它在索引期间进入结构化参数。测试用例,从四个测试用例中,我得到一个选择点是?-dec([0,0,0,1],X)。X=[1,1,1];错。这能改进吗?
:/-& length(Bs,N), dec(Bs, Ds1), dif(Ds1, Ds2), dec(Bs, Ds2).

:/-& length(Ds,N), dec(Bs1, Ds), dif(Bs1, Bs2), dec(Bs2, Ds).

dec([1|Bs],[0|Bs]) :-
   nil_or_ends_with_one(Bs).
dec([0|Bs],[1|Ds]) :-
   deci(Bs, Ds).

nil_or_ends_with_one([]).
nil_or_ends_with_one([E|Es]) :-
   ends_with_one(Es, E).

ends_with_one([], 1).
ends_with_one([E|Es], _) :-
   ends_with_one(Es, E).

deci([1],[]).
deci([1|Bs],[0|Bs]) :-
   Bs = [B|_],
   ends_with_one(Bs, B).
deci([0|Bs],[1|Ds]) :-
   deci(Bs, Ds).
?- dec([1,non_digit,1],[0,non_digit,1]).
% check binary number
num([]).
num([X|Y]) :- dig(X, Y).

dig(1, []).
dig(T, [X|Y]) :- aux(T, X, Y).

aux(0, X, Y) :- dig(X, Y).
aux(1, X, Y) :- dig(X, Y).

% check binary number and its pseudo decrement
dec([X|Y], Z) :- dig(X, Y, Z).

dig(1, [], []).
dig(T, [X|Y], [U|V]) :- aux(T, U, V, X, Y).

aux(0, 1, Z, X, Y) :- dig(X, Y, Z).
aux(1, 0, [X|Y], X, Y) :- dig(X, Y).