Задание 3.
Имеется база фактов, описываемая предикатом person(имя, зарплата): person(иванов, 1500)
person(петров, 2000) person(сидоров, 1200) person(иванов, 1200) ……..
1.Составить список ставок на предприятии (для приведенного примера
[1500,2000,1200]).
2.Найти среднюю зарплату на предприятии.
3.Опубликовать список лиц, получающих зарплату ниже средней.
4.Найти суммарную зарплату Ивановых.
Код программы на Visual Prolog 7.3:
implement main open core, console
constants
className = "main". classVersion = "".
clauses
classInfo(className, classVersion).
domains
list = integer*. s_list = string*.
class facts
person: (string,integer).
class predicates
lowperson : (string) nondeterm(o). add : (list,list,integer) procedure(i,o,i).
no_repeat : (list, list, list) procedure(i,i,o). buildsalarylist : (list) procedure(o). writelist : (list) procedure(i).
writelist : (s_list) procedure(i). salary : (list) procedure(o). findaver : (real) procedure(o).
findsum : (list,integer,integer) procedure(i,i,o). findnum : (list,integer,integer) procedure(i,i,o). lowsalaryunits : (s_list) procedure(o).
sum : (string,integer) procedure(i,o). count : (list,integer,integer) procedure(i,i,o).
clauses person("Underwood",3000). person("Farrar",3000). person("Devereaux",5000). person("Mandrake",2500). person("Lovelace",4500). person("Ivanov",1500). person("Ivanov",3500).
lowperson(N) :- findaver(A), person(N,S), S<A.
add([],[E],E) :- !. add([H|T],[H|T],E) :- H=E, !. add([H|T],[H|T1],E) :- add(T,T1,E).
no_repeat([],RES,RES):-!.
no_repeat([H|T],L,RES) :- add(L,L1,H), no_repeat(T,L1,RES).
buildsalarylist(Q):- salary(L),no_repeat(L,[],Q), !.
writelist([H|T]) :- write(H," "), writelist(T),!. writelist([]) :- !.
salary(Q):-findall(S,person(_,S),Q).
findaver(AVER) :- salary(Q), findsum(Q,0,SUM), findnum(Q,0,N), AVER=SUM/N.
findsum([H|T],K,SUM) :- K1 = K + H, findsum(T,K1,SUM), !. findsum([],K,K) :- !.
findnum([_|T],K,NUM) :- K1 = K + 1, findnum(T,K1,NUM), !. findnum([],K,K).
lowsalaryunits(Q):- findall(N,lowperson(N),L), Q=L.
sum(N,SUM):-findall(S,person(N,S),L), count(L,0,SUM),!.
count([],SUM,SUM):-!. count([H|T],C,SUM):-count(T,C+H,SUM).
clauses run():-
console::init(),
console::clearInput(),
buildsalarylist(Q),
write("List of salaries: "),writelist(Q),nl,
findaver(A), write("Average: ",A),nl,
lowsalaryunits(L),
write("Workers with a low salary: "),writelist(L),nl,
sum("Ivanov",S),
write("Ivanovs' summary salary: ",S),nl, _=readline().
end implement main
goal mainExe::run(main::run).
Рассмотрим функции по порядку:
Общие функции.
writelist(L) – выводит список на экран (аргумент L – выводимый список). salary(L) – вычисляет список L зарплат каждого сотрудника.
Задача 1.
buildsalarylist(L) – составляет список L всех возможных зарплат сотрудников. Используются функции salary, а также no_repeat, которая удаляет все повторы из списка зарплат каждого сотрудника.
Задача 2.
findaver(A) – вычисляет среднюю зарплату А; практически аналогична такой же функции из «Задания 1» за исключением того, что аргумент единственный – список зарплат вычисляется внутри функции.
Задача 3.
lowsalaryunits(L) – составляет список L фамилий сотрудников, чья зарплата ниже средней. Вспомогательная функция: lowperson(N), отсеивающая факты сотрудников с низкой зарплатой, что облегчает их подсчёт с помощью findall.
Задача 4.
sum(N,S) – находит всех сотрудников с фамилией N и с помощью вспомогательной функции Count суммирует их зарплаты в аргумент S.
Результаты работы:
Вывод
В данной лабораторной работе были получены необходимые навыки работы со списками в Visual Prolog 7.3, поверхностно была рассмотрена работа с символами, а также был изучен предикат findall, который использовался для извлечения значений из фактов.