Представление системы уравнений о классах объектов
Я ищу предложения о шаблонах проектирования для того, как описать системы уравнений в Прологе, где каждое уравнение является общим утверждением о классах объектов и точках во времени.
Скажем, что у меня есть: A = 0,5 * B + C^2 и B = 5 * D. Учитывая, например, D = 1 и C = 12, я хочу, чтобы Пролог вычислил значение 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 ответа
Кажется, что путь может использовать ограничения и создавать экземпляры некоторых переменных, например,
:-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))
...и так далее.
Мой первый совет, вероятно, очевиден для вас, который заключается в том, чтобы просто уменьшить количество совпадений в голове с некоторыми предикатами:
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, как если бы у вас был специальный язык программирования, разработанный вами по собственному желанию, и посмотрите, что вы придумали. Тогда, возможно, вы сможете найти способ связать их с помощью переводчика или даже специального переводчика. Например, возможно, ваше время обработки всегда одинаково. Если это так, вы можете полностью выделить его с помощью некоторого кода, который может выглядеть следующим образом:
predator, prey ->> predator * 2, prey / 20.
Такие вещи возможны, если вы определяете новые операторы с правильным порядком приоритета; Таблица существующих операторов приведена в документации. Вы можете создать некоторые пользовательские операторы для них и разработать способ оценки этих выражений путем преобразования класса с чистым атомом в нечто похожее на variable(Class, Name, Value, _)
и пусть он автоматически опережает часы на один шаг. Вы могли бы даже пойти дальше и сначала попробовать в качестве класса и отобразить результаты, либо попробовать использовать его как конкретное имя.