Обратите внимание на то, что списки TripBeliefs и PerformanceBeliefs являются аргументами метода universe() объектов Trip и Manager. Именно здесь объекты предположений получают информацию из предметной области (UniverseOfDiscourse). Прежде чем объект класса proposition вызовет оператор operator(), его контейнер UniverseOfDiscourse должен заполниться имеющимися у агента данными. В листинге 12.10 при вычислении выражения
((Managerl || Manager2 || Manager3) && (Tripl || Trip2 || Trip3));
оценивается шесть предположений (посредством выполнения оператора "||"). Оператор " | |" для каждого предположения выполняет оператор operator (), который для определения истинности предположения использует список UniverseOfDiscourse. Слелует иметь в виду, что классы trip_announcement Hperformance_statement наследуют довольно много функций класса proposition. В листингах 12.6 и 12.7 было показано, как определяется оператор operator() для класса trip_announcement, а в листинге12.11 приведено определение оператора operator () для класса performance_statement.
// Листинг 12.11. Класс performance_statement
bool performance_statement::operator()(void) {
bool Satisfactory = false;
list
I = UniverseOfDiscourse.begin();
while(I != UniverseOfDiscourse.end() && !Satisfactory) {
if(((*I).bays() >= Bays) || ((*I).sales() >= Sales)
|| ((*I).perHour() >=PerHour)){ Satisfactory = true;
}
I++;
}
return(Satisfactory);
}
Оператор operator () для каждого класса proposition играет «свою» роль в способности класса агента делать логические выводы. В листинге 12.6 показано, как вызывается оператор operator () при каждом вычислении оператора " || " или "&&" для класса proposition или для одного из его потомков. Именно такое сочетание методов operator (), определенных в proposition-классах, и методов класса agent образует стратегии логического вывода для класса agent. В дополнение к операторам "||" и "&&", определенным в классе proposition, классы trip_announcement и performance_statement содержат свои определения.
friend bool operator||(bool X,trip_announcement &Y); friend bool operator&&(bool X,trip_announcement &Y);
Эти friend -объявления позволяют использовать предположения в более длинных выражениях. Сделаем следующие объявления.
//. . .
trip_announcement А, В, С; bool X;
X = А || В || С;
//.. .
При этом объекты А и В будут объединены с помощью операции ИЛИ, а результат этой операции будет иметь тип bool. Затем мы попробуем с помощью той же операции ИЛИ получить значение типа bool и объект типа trip_announcement: bool || trip_announcement
Без приведенных выше friend -объявлений такая операция была бы недопустимой. Определение этих функций-«друзей» показано влистинге 12.12.
// Листинг 12.12. Перегрузка операторов "||" и "&&"
bool operator||(bool X,trip_announcement &Y) {
return(X | | YO) ;
}
bool operator&&(bool X,trip_announcement &Y) {
return(X && Y());
}
Обратите внимание на то, что в определении этих функций-«друзей» (благодаря ссылке на элемент Y ()) также используется вызов функции operator (). Эти функции определяются и в классе performance_statement. Наша задача — сделать использование proposition-классов таким же простым, как использование встроенных типов данных. В классе proposition также определен другой оператор, который позволяет использовать предположение естественным образом. Рассмотрим следующий код.
//.. .
trip_announcement А; if(A) {
//... Некоторые действия.
}
//.. .
Как в этом случае компилятор тестирует объект А? При выполнении инструкции if () компилятор стремится найти в скобках значение целочисленного типа данных или типа bool. Но тип объекта А совсем другой. Мы хотим, чтобы ко
template
return((void*)(TruthValue));
}