Представление линейных функций в прологе

Я хочу написать составные термины, которые представляют линейные отношения между различными переменными в совокупности в форме Y = a + b*X (например, fuelConsidity = 2 + 3 * distance, для совокупности, состоящей из автомобилей). У меня есть проблемы с утверждением, что отношение относится к населению (группе), в то же время утверждая, что значения для каждой переменной связаны внутри объектов (то есть, что потребление топлива автомобилем A составляет 2 + 3 * расстояния автомобиля A, а не расстояния автомобиля B).


Это может означать, что отношение относится к совокупности, но в нем явно не указывается, что значения каждой переменной связаны внутри объектов:

causes(
    cause(distance),
    effect(fuelConsumption),
    a(2),
    b(3)
).

И наоборот, это фиксирует, что значения каждой переменной связаны внутри объектов, но пропускает, что соединение является отношением (линией). Каждый экземпляр этого соединения представляет две точки, но я хотел, чтобы каждый экземпляр был линией.

car(aCar).
car(anotherCar).
causes(
        cause(Car, distance, D),
        effect(Car, fuelConsumption, F)
):- car(Car), F #= 2 + 3 * D.

Это кажется ближе к решению, но я все еще не очень удовлетворен по двум причинам: 1. Утверждение о линейном отношении должно быть справедливо для любой совокупности, а не только для объектов, которые я случайно указал в терминах совокупности; 2. Функция, которая связывает расстояние с расходом топлива, не указана явно (например, как насчет экспоненциального отношения и т. Д.?).

population([car1, car2, car3, car4]).
causes(
    cause(P, distance),
    effect(P, fuelConsumption),
    a(2),
    b(3)
):-population(P).

Любая помощь будет принята с благодарностью. Моя цель состоит в том, чтобы объявить отношения максимально точно и прозрачно (т.е. должны быть понятными для человека).

Спасибо!

/ JC

Некоторые ссылки на связанные вопросы:
представление системы уравнений о классах объектов,
как-к-закодировать-причинные-отношения-в-пролог-а-а-линейно-функции

1 ответ

Решение

Это просто еще один слепой удар по вашей проблеме. Это интересная проблема. Но я должен признаться, я всегда чувствую, что это что-то вроде ситуации XY, где, если бы я знал больше о вашем контексте, я был бы лучше понять, почему вы ищете что-то, что кажется мне настолько сложным.

/*

For all cars in a set, distance causes fuelConsumption; and for any
car in this set, that car’s fuel consumption can be obtained as
2 + 3 * distance for that car.

*/

% prop(Set, PropertyName)
prop(car, distance).
prop(car, fuelConsumption).

% entity(Set, Individual, Properties)
entity(car, car1, [distance=23]).
entity(car, car2, [distance=0]).

%% There are two ways to find a property value:
%%
%%   1. Look for the property in the individual's properties
propvalue(Set, Individual, Property, Value) :-
    entity(Set, Individual, Properties),
    memberchk(Property=Value, Properties).

%%   2. Compute the property using other aspects of the individual
propvalue(Set, Individual, Property, Value) :-
    causes(Set, Individual, Property, Value, Query),
    call(Query).

%% causes(Set, Individual, Property, Value, Goal)
causes(car, C, fuelConsumption, V,
       (propvalue(car, C, distance, D), V is 2 + 3 * D)).

Поэтому моя основная идея заключается в том, чтобы овеществлять ваши объекты. prop/2 действительно здесь для размышления, но я не использую это в настоящее время. propvalue/4 тезисы о том, являются ли свойства причинами или следствиями, предоставляя вам одинаковый доступ к любому из них.

Ключевая идея здесь causes/5, Это не самый эстетически приятный способ представления данных, но я думаю, что он объединяет основные идеи, которые у вас есть: что во всем этом наборе это свойство получается с помощью этого расчета. На самом деле здесь не представлена ​​идея причины; Я просто не видел смысла в этом. Я ожидал бы, если бы это был мой код, что в целом я бы передавал Автомобиль в этот расчет и все свойства автомобиля, которые вам нужны, вы просто получаете. Но я никогда не до конца понимал вашу интересную проблему.

Если это близко, есть вещи, которые вы можете сделать, чтобы сделать интерфейс лучше. Вы можете заменить первые два аргумента causes/5 с чем-то вроде car(C) и использовать =../2 собрать этот параметр в propvalue/4, Вы также можете использовать :- отделить цель от головы и использовать current_predicate/3 повторно получить цель тела в propvalue/4, Объединяя эти идеи, вы получите более простой causes/3 это будет выглядеть так:

propvalue(Set, Individual, Property, Value) :-
    SetIndividual =.. [Set, Individual],
    call(causes, SetIndividual, Property, Value).

causes(car(C), fuelConsumption, V) :-
    propvalue(car, C, distance, D),
    V is 2 + 3 * D.

Идея в том, что causes/3 правила действительно действуют как структура данных, к которой propvalue/4 чем то, что вы собираетесь позвонить напрямую. propvalue/4 Перечислим все свойства (вычисленные и не вычисленные) всех сущностей в различных группах населения. Вы могли бы, вероятно, улучшить читаемость, изменив propvalue/4 в propvalue/3 и делать =../2 разрушая здесь вместо Но я думаю, что это сработает, вы захотите получить табличное представление вашего населения, сродни entity/3, с не вычисленными свойствами для каждого там.

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

Во всяком случае, в настоящее время это мое лучшее предположение о том, что вы ищете, я надеюсь, что это поможет.

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