Представление системы уравнений о классах объектов

Я ищу предложения о шаблонах проектирования для того, как описать системы уравнений в Прологе, где каждое уравнение является общим утверждением о классах объектов и точках во времени.

Скажем, что у меня есть: 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, _) и пусть он автоматически опережает часы на один шаг. Вы могли бы даже пойти дальше и сначала попробовать в качестве класса и отобразить результаты, либо попробовать использовать его как конкретное имя.

Другие вопросы по тегам