Prolog表示的平行线定理推理

huangapple go评论63阅读模式
英文:

Prolog Representation for Parallel Line Theorem Reasoning

问题

我使用Prolog来推理关于平行线定理的问题。

即,AB || EF 和 CD || EF,这导致了AB || CD。

当前的代码确保AB || CD为真,但BA || CD为假。
是否有办法使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,应该为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)).

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

英文:

I am using prolog for reasoning about theorems for parallel lines.

That is, AB || EF and CD || EF, which leads to AB || CD.

The current code ensures that AB || CD is true, but BA || CD is false.
Is there any way to make BA || CD is also true?

M and N are to control the number of executions, which I guess is not related to the problem.

Here is my code:

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).

The query I executed:

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

I know I can use this method to solve the problem, but the number of rules needed is 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)).

Is there a more elegant way to solve this problem?

答案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/2 同样的方式将其设为非递归。)

英文:

Try this:

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)).

This uses the nonrecursive relation parallel_base, allowing the endpoints of the lines to be given in any order. I didn't use your seg/1 predicate because it's recursive and you may get endless recursion. (I recommend you comment it out, or make it nonrecursive in the same way you made parallel/2 nonrecursive by using parallel_base.)

答案2

得分: 0

我只想提一下 - 而不是:

  ((A=W,B=X);(A=X,B=W)),
  ((C=Y,D=Z);(C=Z,D=Y)),

... 一个更简洁的替代方法是强制使用较低(或相等)的值在前,例如:

lower_upper(X, Y, L, U) :-
    (   X @< Y
    ->  L = X, U = Y
    ;   L = Y, U = X
    ).

这将有助于减少不必要的选择点,并提高代码的清晰度。

英文:

I just wanted to mention - rather than:

  ((A=W,B=X);(A=X,B=W)),
  ((C=Y,D=Z);(C=Z,D=Y)),

... a neater alternative is to enforce the convention of the lower (or equal) value being first, using e.g.:

lower_upper(X, Y, L, U) :-
    (   X @&lt; Y
    -&gt;  L = X, U = Y
    ;   L = Y, U = X
    ).

This will help to reduce the amount of unwanted choicepoints, and improve code clarity.

huangapple
  • 本文由 发表于 2023年3月31日 17:39:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75896980.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定