Представление линейных функций в прологе
Я хочу написать составные термины, которые представляют линейные отношения между различными переменными в совокупности в форме 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, которая имеет несколько врожденных представлений об объекте, которые, вероятно, сделают ваш дизайн более простым. Мне кажется, что вы устали бы от необходимости писать свою собственность настолько многословно, и в этом случае вы, вероятно, получили бы большую пользу от реальных объектов или от введения собственного синтаксиса и его синтаксического анализа.
Во всяком случае, в настоящее время это мое лучшее предположение о том, что вы ищете, я надеюсь, что это поможет.