平行线定理推理的序言表示

问题描述 投票:0回答:1

我正在使用 prolog 来推理平行线的定理。

即AB || EF 和 CD || EF,导致 AB ||光盘

当前代码确保 AB || CD 是真的,但是 BA ||光盘是假的。 有没有办法让BA || CD也是这样吗?

M和N是控制执行次数,我估计跟问题无关

这是我的代码:

seg(A,B):-seg(B,A).
parallel(seg(A,B),seg(C,D),N):-M is N - 1,M >= 0,parallel(seg(A,B),seg(E,F),M),parallel(seg(C,D),seg(E,F),M).
parallel(A,B,N):-M is N - 1,M >= 0,parallel(B,A,M).
parallel(A,B,N):-M is N - 1,M >= 0,parallel(A,B,M).
parallel(seg(a,b),seg(e,f),0).
parallel(seg(c,d),seg(e,f),0).

我执行的查询:

parallel(seg(a,b),seg(c,d),2). ------true
parallel(seg(b,a),seg(c,d),2). ------false,should be true

我知道我可以用这个方法来解决问题,但是需要的规则数是2^N。

parallel(seg(A, B), seg(C, D)) :- parallel_base(seg(A, B), seg(C, D)).
parallel(seg(A, B), seg(D, C)) :- parallel_base(seg(A, B), seg(C, D)).
parallel(seg(B, A), seg(C, D)) :- parallel_base(seg(A, B), seg(C, D)).
parallel(seg(B, A), seg(D, C)) :- parallel_base(seg(A, B), seg(C, D)).

有没有更优雅的方法来解决这个问题?

prolog
1个回答
0
投票

试试这个:

parallel(seg(A, B), seg(C, D)) :- 
  ((A=W,B=X);(A=X,B=W)),
  ((C=Y,D=Z);(C=Z,D=Y)),
  parallel_base(seg(W, X), seg(Y, Z)).

这使用非递归关系

parallel_base
,允许以任何顺序给出线的端点。我没有使用你的
seg
/1 谓词,因为它是递归的,你可能会得到无穷无尽的递归。 (我建议你把它注释掉,或者像你使用
parallel
使
parallel_base
/2 非递归的方式一样使它成为非递归。)

© www.soinside.com 2019 - 2024. All rights reserved.