Взгляд на работу программы
Программа начинает работу с загрузки базы знаний. Файлы базы знаний имеют расширение *.kbs.Выбранный файл загружается и проверяется на наличие синтаксических ошибок. Правила, записанные в базе знаний, транслируются к удобному для работы системы виду внутреннего представления, а именно в виде фактов динамической базы данных:
сl ( "hypothesis", "plane", 0.5, bayes_rule ( [ contrib ("plane_factors", 1, 0.001), contrib ("plane_speed", 5, 1), contrib("plane_cost", 5, 0.5),
contrib ("plane_dist", 10, 0.9) ] ), "Use a plane","", [ ] )
cl ( "hypothesis", "car", 0.5, bayes_rule ( [ contrib ("car_factors", 1, 0.9),
contrib ("car_speed", 5, 0.9), contrib ("car_dist", 2, 0.8), contrib ("car_cost", 3, 0.9) ] ), "Use a car", "", [ ] )
cl ( "hypothesis", "train", 0.5, bayes_rule ( [ contrib ("rail_factors", 1.1, 1),
contrib ("drive_yourself", 1.1, 1), contrib ("rail_speed", 1.1, 0.1),
contrib ("rail_dist", 2, 1), contrib ("rail_cost", 5, 1) ] ), "Use a train", " ", [ ] )
cl ( "intermediate", "rail_factors", 0.5, and_rule ( [ "drive_yourself", "rail_speed", "rail_dist", "rail_cost" ] ), "use of a train is appropriate", "", [ ] )
cl ( "intermediate", "rail_speed", 0.5, num_map_rule ("speed", [ nummap (60, 1), nummap (150, 0) ] ), "Desired journey speed permits rail use", "",
[context ("drive_yourself", – 5, 0) ] )
cl ( "intermediate", "rail_dist", 0.5, num_map_rule ("distance", [nummap (50, 0), nummap (200, 1), nummap (350, 0) ] ), "Is the use of a train sensible", "", [context("drive_yourself", – 5, 0) ] )
cl ( "intermediate", "rail_cost", 0.5, num_map_rule ("cost", [ nummap (10, 0), nummap (20,1) ] ), "Desired cost per mile is possible using a train", "", [context ("drive_yourself", – 5, 0) ] )
cl ( "data", "drive_yourself", 0.5, yesno_rule,"Do you want to drive yourself?", "", [ ] )
cl ( "data", "distance", 0.5, num_value_rule (0.1,30000), "what is the distance of the journey in miles?", "", [ ] )
cl ( "data", "speed", 0.5, num_value_rule (1, 1300), "what is the required average speed for the journey (mph)?", ", [ ] )
cl ( "data", "cost", 0.5, num_value_rule (1, 50), "How much are you prepared to pay per mile?", "This system assumes the costs:\n plane: 30 cents/mile\n train: 25 cents/mile \n car: 20 cents/mile", [ ] )
. . .
Основная цель программы – вычислить значение определенности для выбранной гипотезы. Информация для этого поступает через data-правила и из фактов, запомненных во временной базе данных. Предикат evaluate устанавливает уровень определенности, выбирает гипотезу и запускает предикат eval, оценивающий определенность одного правила. Поскольку правило может ссылаться на список других правил, следует оценить определенность каждого элемента такого списка. Эту работу выполняет предикат evalbody. Это рекурсивный предикат, в котором определенность каждого элемента вычисляет eval:
evalbody ( not_rule ( Clname ), Desc, Prior,
num ( Val ), Anceslst, Mode ) :–
eval ( not_rule, _ , Clname, _ , num ( Val1 ), Anceslst, Mode ),
Val = 1 – Val1.
evalbody ( and_rule ( [ ] ), _ , _ , num ( 1 ), _ , _ ) :– !.
evalbody ( and_rule ( [ Clname | T ] ), Desc, Prior,
num ( Val ), Anceslst, Mode ) :–
eval ( and_rule, _ , Clname, _ , num ( Val1 ) , Anceslst, Mode ),
evalbody ( and_rule ( T ), Desc, Prior, num ( Val2 ), Anceslst, Mode ),
min ( Val1, Val2, Val ).
evalbody ( or_rule ( [ ] ), _ , _ , num (0), _ , _ ) :– !.
evalbody ( or_rule ( [ Clname | T ] ), Desc, Prior,
num( Val ), Anceslst,Mode ) :–
eval ( or_rule, _ , Clname, _ , num( Val1 ), Anceslst, Mode ),
evalbody ( or_rule( T ), Desc, Prior, num ( Val2 ), Anceslst, Mode ),
max ( Val1, Val2, Val ).
evalbody ( bayes_rule ( [ ] ), _ , Prior, num ( Prior ), _ , _ ) :– !.
evalbody ( bayes_rule ( [ contrib ( Clname, Inc, Dec ) | T ] ), Desc, Prior,
num ( Val ), Anceslst, Mode) :–
eval ( bayes_rule, _ , Clname, Pri, num ( Val1 ), Anceslst, Mode ),
evalbody ( bayes_rule ( T ), Desc, Prior, num ( Val2 ), Anceslst, Mode ),
combinebayes ( Pri, Val1, contrib ( Clname, Inc, Dec ), Val2, Val ).
evalbody ( sym_map_rule ( Clname, L ), Desc, Prior, num (Val),
Anceslst, Mode ):–
eval ( sym_map_rule, _ , Clname, _ , Val1, Anceslst, Mode ),
calcsymrule ( sym_map_rule ( Clname, L ), Prior, Val1, Val ).
. . .
Одно из самых сложных мест здесь – вычисление определенности в случае, когда заданы весовые коэффициенты правил. Здесь следует учитывать сочетание параметров PRIOR, BAYES и введенного пользователем значения определенности. Эту работу выполняет предикат combinebayes, который возвращает значение аргументом Ans:
сombinebayes ( ClPrior, ClVal, contrib ( _ , Inc, Dec), RestVal, Ans ) :–
probtoodds ( RestVal, RestOdds ),
bayesfactor ( ClVal, ClPrior, Dec, Inc, F ),
Odds = F * RestOdds,
oddstoprob ( Odds, Ans ).
Предикат combinebayes запускает probtoodds, обращающий вероятность уже оцененных правил в промежуточное значение по формуле:
ROOS = PROB / ( 1 – PROB ) .
Bayesfactorвычисляет константу F, учитывающую весовые факторы, для случаев PRIOP < PROBиPRIOR > PROB:
bayesfactor ( Prob, Prior, Dec, Inc, F ) :–
Prior > = Prob,
!,
probtocert ( Prob, Prior, Cert ),
F = (( 1 – Dec) * ( Cert + 5) / 5) + Dec.
bayesfactor ( Prob, Prior, Dec, Inc, F ) :–
probtocert ( Prob, Prior, Cert),
F = 1 + ( Inc – 1) * Cert / 5.
/* Обращает вероятность в определенность */
probtocert ( _ , 0, – 5 ):– !.
probtocert ( _ , 1, 5 ):– !.
probtocert ( Prob, Prior, Cert ) :–
Prob < = Prior,
Cert = 5 * Prob / Prior – 5,
!;
Cert = 5 * ( Prob – Prior) / ( 1 – Prior).
Предикатoddstoprob обращает полученное промежуточное значение обратно в вероятность:
oddstoprob ( Odds, Prob ):–
Prob = Odds / ( 1 + Odds ).
В некоторых правилах возникает необходимость обратить определенность в вероятность, например, при вводе значения определенности data-правила с помощью функции CERTAINTY. Это делает предикат certtoprobпо формулам преобразования, обратным обращению вероятности в определенность:
certtoprob ( Cert, Prior, Value ):–
Cert < = 0, Value = Prior * ( Cert + 5 ) / 5,
!;
Value = Prior + ( 1 – Prior ) * Cert / 5.