英文:
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 @< Y
-> L = X, U = Y
; L = Y, U = X
).
This will help to reduce the amount of unwanted choicepoints, and improve code clarity.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论