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