表示关于对象类别的方程组

时间:2018-08-20 17:16:45

标签: prolog

我正在寻找有关如何描述Prolog中方程组的设计模式的建议,其中每个方程都是关于对象和时间点类别的一般说明。

说我有: A = 0.5 * B + C ^ 2,而B = 5 * D. D = 1和C = 12,我希望Prolog计算A的值。但是,在A,B,C和D是对象和时间的一般类的情况下,我想这样做。下面的代码可以正常工作,但是我发现它有些冗长,尤其是原因谓词主体中的描述谓词(我的描述谓词比示例中的描述谓词更长)。我的目标也是使代码透明并且易于他人阅读。

有人建议如何表示示例代码中的问题吗?

谢谢!

predator(fox).
predator(lion).
prey(rabbit).
prey(deer).
time(1).
time(2).
time(3).

value(description(fox, at, 1), 100).

value(Description, Value):-
    causes(
        _,
        variable(name(_), value(Value), Description)
        ).

causes(
    variable(name(predators), value(X), description(Predator, at, Time1)),
    variable(name(prey), value(Y), description(Prey, at, Time2))
)
:-
predator(Predator), prey(Prey), time(Time1), time(Time2), Time2 > Time1,
value(description(Predator, at, Time1), X), Y is 10 / X.

causes(
    variable(name(prey), value(X), description(Prey, at, Time1)),
    variable(name(predators), value(Y), description(Predator, at, Time2))
)
:-
predator(Predator), prey(Prey), time(Time1), time(Time2), Time2 > Time1,
value(description(Prey, at, Time1), X), Y is 20 / X.

编辑1: 上面的知识库的示例调用:

?-causes(A, B).

例如返回:

A = variable(name(predators), value(100), description(fox, at, 1)),
B = variable(name(prey), value(0.1), description(rabbit, at, 3))

编辑2: 具有三个变量的示例:

relation(
    effect(variable(name(prey), value(Y), description(Prey, at, Time2))),
    causes([
        variable(name(predators), value(X), description(Predator, at, Time1)),
        variable(name(amountOfFood), value(Z), description(Food, at, Time1))
    ])
)
:-
predator(Predator), prey(Prey), time(Time1), time(Time2), Time2 > Time1, food(Food),
value(description(Predator, at, Time1), X), value(description(Food, at, Time1), Z),
Y is 20 / X * 3 * Z.

2 个答案:

答案 0 :(得分:2)

我的第一条建议可能对您很明显,这只是为了减少与某些谓词的匹配量。

varname(variable(name(Name), _, _), Name).
varvalue(variable(_, value(Value), _), Value).
varproperty(variable(_, _, description(Property, at, Value)), Property, Value).

然后您可以像这样简化某些谓词:

causes(PredatorVar, PreyVar) :-
    varname(PredatorVar, predators), varvalue(PredatorVar, X),
    varname(PreyVar, prey), varvalue(PreyVar, Y),
    varproperty(PredatorVar, Predator, Time1),
    varproperty(PreyVar, Prey, Time2),
    predator(Predator), prey(Prey),
    Time2 > Time1, Y is 10 / X.

这种“简化”的价值有些可疑。

我正在写的另一件事对我来说是,也许您不需要像您一样对函子参数进行太多的包装。您会满足于这样的事情吗?

:- op(700, xfx, at).

causes(variable(predators, X, Predator at Time1),
       variable(prey, Y, Prey at Time2)) :-
    predator(Predator), prey(Prey), time(Time1), time(Time2), Time2 > Time1,
    value(description(Predator, at, Time1), X), Y is 10 / X.

我认为另一种有利可图的方法是,首先编写这些谓词而无视Prolog,就好像您有自己定制设计的特殊编程语言,然后看看自己会想到什么。然后,也许您可​​以找到一种使用解释器甚至custom metainterpreter来桥接两者的方法。例如,也许您的时间处理总是相同的。如果是这样,您可以通过一些看起来像这样的代码将其完全排除:

predator, prey ->> predator * 2, prey / 20.

如果您使用正确的优先顺序定义新的运算符,则可能会发生这种情况;现有运算符的表为given in the documentation。您可以为此创建一些自定义运算符,并设计一种方法来评估这些表达式,方法是将裸原子类转换为类似于variable(Class, Name, Value, _)的东西,并使它自动向前移动一步。您甚至可以走得更远,让它首先作为一个类尝试并映射结果,或者尝试将其用作特定名称。

答案 1 :(得分:1)

一种可行的方法似乎是使用约束并实例化一些变量,例如

:-use_module(library(clpr)).

predator(fox).
predator(lion).
prey(rabbit).
prey(deer).
time(1).
time(2).
time(3).

causes(
    variable(name(predators), value(X), description(Predator, at, Time1)),
    variable(name(prey), value(Y), description(Prey, at, Time2))
)
:-
predator(Predator), prey(Prey), time(Time1), time(Time2), Time2 > Time1,
{Y = 10 / X}.

causes(
    variable(name(prey), value(X), description(Prey, at, Time1)),
    variable(name(predators), value(Y), description(Predator, at, Time2))
)
:-
predator(Predator), prey(Prey), time(Time1), time(Time2), Time2 > Time1,
{Y = 20 / X}.

例如,给出目标:

causes(X, variable(name(prey), value(15), description(Prey, at, Time2))).

收益:

Prey = rabbit,
Time2 = 2,
X = variable(name(predators), value(0.6666666666666666), description(fox, at, 1))

...等等。