【问题标题】:How to interface Prolog CLP(R) with real vectors?如何将 Prolog CLP(R) 与实向量接口?
【发布时间】:2018-07-01 21:08:40
【问题描述】:

我正在使用 Prolog 来求解简单的几何方程。 例如,我可以将通过两个点 p1p2 的线上的所有点 p3 定义为:

   line((X1, Y1, Z1), (X2, Y2, Z2), T, (X3, Y3, Z3)) :-
        {(X2 - X1) * T = X3},
        {(Y2 - Y1) * T = Y3},
        {(Z2 - Z1) * T = Z3}.

然后像line((0, 0, 0), (1, 1, 1), _, (2, 2, 2)) 这样的谓词为真。

但我真正想要的是写下这样的东西:

line(P1, P2, T, P3) :- {(P2 - P1) * T = P3}.

其中 P1、P2 和 P3 是实向量。

达成类似目标的最佳方式是什么?到目前为止我发现的最好的方法是重写我自己的 addsubtractmultiply 谓词,但这并不方便。

【问题讨论】:

    标签: vector prolog clp clpr


    【解决方案1】:

    这是一个解决方案,您仍然需要为要处理的每个运算符编写一些代码,但它仍然在使用时提供了很好的语法。

    让我们从将向量上的算术表达式计算为向量的概念开始。这实质上是按组件应用算术运算。 (但你可以添加点积或任何你喜欢的东西。)

    :- use_module(library(clpr)).
    
    vectorexpr_value((X,Y,Z), (X,Y,Z)).
    vectorexpr_value(V * T, (X,Y,Z)) :-
        vectorexpr_value(V, (XV,YV,ZV)),
        { X = XV * T },
        { Y = YV * T },
        { Z = ZV * T }.
    vectorexpr_value(L + R, (X,Y,Z)) :-
        vectorexpr_value(L, (XL,YL,ZL)),
        vectorexpr_value(R, (XR,YR,ZR)),
        { X = XL + XR },
        { Y = YL + YR },
        { Z = ZL + ZR }.
    vectorexpr_value(L - R, (X,Y,Z)) :-
        vectorexpr_value(L, (XL,YL,ZL)),
        vectorexpr_value(R, (XR,YR,ZR)),
        { X = XL - XR },
        { Y = YL - YR },
        { Z = ZL - ZR }.
    

    例如:

    ?- vectorexpr_value(A + B, Result).
    A =  (_1784, _1790, _1792),
    B =  (_1808, _1814, _1816),
    Result =  (_1832, _1838, _1840),
    {_1808=_1832-_1784},
    {_1814=_1838-_1790},
    {_1816=_1840-_1792} .
    

    鉴于此,我们现在可以通过“评估”向量表达式并在结果上断言逐点相等来定义向量表达式的“相等”。为了让它看起来更漂亮,我们可以为它定义一个操作符:

    :- op(700, xfx, ===).
    

    这将=== 定义为中缀运算符,与其他相等运算符==:= 等具有相同的优先级。Prolog 不允许您重载运算符,因此我们制作了一个新运算符。您可以将运算符中的三个= 符号视为在三个维度上表示相等。

    下面是对应的谓词定义:

    ExprL === ExprR :-
        vectorexpr_value(ExprL, (XL,YL,ZL)),
        vectorexpr_value(ExprR, (XR,YR,ZR)),
        { XL = XR },
        { YL = YR },
        { ZL = ZR }.
    

    我们现在几乎可以按照您的意愿定义line/4

    line(P1, P2, T, P3) :-
        (P2 - P1) * T === P3.
    

    测试:

    ?- line((0,0,0), (1,1,1), Alpha, (2,2,2)).
    Alpha = 2.0 ;
    false.
    
    ?- line((0,0,0), (1,1,1), Alpha, (2,3,4)).
    false.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多