我正在寻找有关如何描述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.
答案 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))
...等等。