Система "Посередник". Укладання договорів на постачання будівельних матеріалів
Введення
Наприкінці двадцятого століття автоматизація все сильніше завойовує всі сфери людської діяльності. Застосування обчислювальної техніки в різноманітних галузях народного господарства покликане полегшити працю людини і зменшити число помилок, що здійснюються при прийнятті рішень.
При побудові систем, що допомагають людині, використовуються прийоми, досліджувані такою областю інформатики, як інженерія знань.
В даному курсовому проекті реалізована система "Посередник", що служить для укладання договорів між постачальниками та покупцями будівельних матеріалів. Ця система може використовуватися співробітниками посередницьких контор, що працюють у цій галузі.
Програма реалізована на мові Пролог.
1. Види послуг та режими роботи системи "Посередник"
Основне призначення системи "Посередник" - надання послуг з укладання договорів між постачальниками та покупцями будівельних матеріалів. Укладання договорів може проводитися в звичайному, або в інтерактивному режимі. У першому випадку система укладає контракт на основі наявної в базі даних інформації про клієнтів, у другому випадку система запрошує дані у користувача, після чого шукає необхідну інформацію в базі даних і, знайшовши відповідні договори, виводить їх, або за відсутності на даний момент можливостей для угоди, заносить інформацію про клієнта в базу даних. Крім всіх можливих варіантів договорів система виводить ще й найбільш бажані для посередника з точки зору комерційної вигоди.
Крім того, в системі є режими перегляду і редагування (або додавання) даних по постачальникам і по покупцям, а також перегляду і редагування регіональної приналежності фірм-виробників. Якщо під час роботи з програмою в бази даних були внесені які-небудь зміни, то при виході з програми за згодою користувача буде вироблено збереження змін.
2. Концептуальна модель знань, необхідних для надання послуг
Концептуальна модель предметної області представляється безліччю класів об'єктів з заданими на ньому відносинами і операціями. Класи об'єктів характеризуються деяким набором атрибутів.
В даному курсовому проекті класами об'єктів є Попит, Пропозиція і Договір. Клас, Попит, має наступні атрибути: порядковий номер, назва фірми, назва товару, виробник, бажаної партії товару, ціна за одиницю товару і термін постачання. У класу Пропозиція, є такі ж атрибути, за винятком того, що замість бажаної партії товару тут присутні мінімальна партія і максимальна кількість товару, що є у постачальника.
Уявімо об'єкти класів Попит і Пропозиція у вигляді таблиць:
Таблиця об'єктів класу Попит
№
Фірма
Товар
Виробник
Кількість
Ціна, $
Термін постачання
1
ДСК-3
Цегла лицювальна
россійская
1000
0.33
6
2
Мосжілстрой
Керамзит
європейська
30
22
8
3
Геракл
Арматура сталева
СНД
15
51
10
4
МВМ
Азбест будівельний
українська
70
20
7
5
АТС-50
Кабель АВВГ
россійская
1000
2
18
6
БМУ-35
Керамзит
россійская
120
20
6
7
РЕУ-22
Скло віконне
білоруська
500
3
10
8
Атлант
Шпалери що миються
Vertex
1000
4
14
9
Sunpride
Цегла лицювальна
московська
800
0.4
10
10
Hausbauer
Плитка лицювальна
італійська
1000
11
7
11
БМУ-28
Ванна
європейська
40
350
20
12
Протон
Кабель АВВГ
московська
1000
21
4
Таблиця об'єктів класу Пропозиція
№
Фірма
Продукція
Виробник
мін. партія
Макс. партія
Ціна, $
Термін постачання
1
Будсервіс
Цегла лицювальна
2-й цегляний
120
900
0.25
7
2
Оріон
Керамзит
Електроізоліт
10
50
20
4
3
Салют
Арматура сталева
ММЗ
1
20
50
8
4
Будсервіс
Кабель АВВГ
Іркутсккабель
900
9000
1
11
5
Байрамікс
Азбест будівельний
Стройперліт
30
100
15
9
6
Все для дому
Кабель АВВГ
ММЗ
900
9000
1
12
7
Спецстрой
Скло віконне
Серп і молот
50
700
2
10
8
Астра
Шпалери що миються
Vertex
1000
9000
3
11
9
Глобус
Азбест будівельний
Донецкбетон
10
200
15
6
10
Орбіта
Цегла лицювальна
Мосбетон
2000
9000
0.3
4
11
Все для дому
Плитка лицювальна
Marlit
1000
8000
10
6
12
Ункомтех
Кабель АВВГ
Іркутсккабель
700
1200
0.9
8
13
Електросталь
Арматура сталева
ММЗ
7
20
65
3
14
Arkon
Паралон рідкий
Interchemall
3000
9000
10
10
15
Worms
Ванна сталева
Nord Star
35
1000
300
18
Концептуальна схема предметної області представлена на рис.1. і рис.2.
Рис.1. Концептуальна схема предметної області (попит та пропозиція).
Рис.2. Концептуальна схема предметної області (договір).
3. Представлення даних про клієнтів
Дані про клієнтів в системі "Посередник" представлені у вигляді стандартних баз даних (database) мови Пролог. Оскільки в Пролозі є досить потужний механізм роботи з такими базами даних, реалізувати на ньому програму типу системи "Посередник" набагато простіше і природніше, ніж на алгоритмічних мовах (типу Pascal або C).
Загальний вигляд записів у базах даних наступний:
постачальник (N, F, T, P, M, X, C, D)
покупець (N, F, T, P, K, C, D)
де N - номер запису, F - фірма-постачальник, T - найменування товару, P - виробник товару, M - мінімальна партія, X - наявна партія, С - ціна за одиницю товару, D - термін поставки, K - потрібне покупцеві кількість товару. N, M, X, K, D - цілочисельні, F, T, P - рядкові, С - дійсна.
База даних по постачальникам записана у файлі kurs1.dat, за покупцям - в kurs2.dat.
4. Мережева модель представлення знань і її використання для отримання довідкової інформації і формування варіантів договору
Мережева модель реалізується за допомогою так званих семантичних мереж. У семантичній мережі імена деяких об'єктів, процесів, дій, сутностей та їх класів асоціюються з вузлами, а відносини між ними асоціюються з дугами, що сполучають вузли. Мережну модель можна представити у вигляді такої конструкції: S = , де I - безліч інформаційних одиниць, С1, С2, ..., Сn - безліч типів зв'язків між інформаційними одиницями, Г - відображення, що задає зв'язку (із заданої множини типів зв'язків) між інформаційними одиницями, що входять в I.
що класифікують мережі (використані в даній курсовій), на ряду з функціональними, є одним з класів однорідних (у яких дуги тільки одного типу) мереж. Що класифікують мережі будуються на основі родовідового відносини sup b>, заданого на множині класів об'єктів. Це відношення інтерпретується наступним чином: якщо Ki sup b> Kj, то в будь-який момент часу t кожен об'єкт класу Ki є об'єктом класу Kj, тобто Kj є підкласом Ki (або Ki є підкласом Kj). Конкретні об'єкти, як правило, пов'язуються з класами нижчого рівня ієрархії ставленням приналежності isa b>. Запис ki isa b> K означає, що об'єкт ki є елементом класу K.
В даному курсовому проекті класифікує мережа використовується для визначення регіональної приналежності виробника будівельних матеріалів. Завдяки цьому при укладанні договорів покупцеві не обов'язково задавати конкретного виробника, а можна встановити тільки регеон розташування тих виробників, продукція яких покупцеві здається найкращою.
У системі "Посередник" є також можливість отримання інформації про приналежність будь-якого виробника регіону шляхом перегляду зв'язків у класифікує мережі, а так само є режими коректування і доповнення цієї мережі.
Графічне подання класифікує мережі показано на рис.3.
Програмно класифікує мережа реалізована у вигляді стандартних баз даних Прологу (database) і виглядає таким чином:
sup (Ki, Kj)
де Ki та Kj - клас і його підклас відповідно.
класифікує мережа знаходиться у файлі web.dat.
5. Критерії вибору найбільш кращого варіанту договору
В даному курсовому проекті найбільш кращий договір вибирається на користь посередника. Вигода посередника полягає в отриманні найбільшого прибутку в найкоротші терміни. Дохід посередника зазвичай складає деякий комісійний відсоток від укладеної угоди, тому найбільш вигідні контракти, в яких твір кількості товару, необхідне покупцеві на ціну цього товару, призначену продавцем, буде максимальним. Це і буде першим критерієм вибору найбільш пріоритетним договору. Другим критерієм, як було сказано вище, буде найкоротший термін поставки.
На початку програма вибирає переважні договори за першим критерієм. Якщо таких договорів вийде декілька, то програма вибирає з них той, у якого термін поставки менше (тобто реалізується другий критерій).
Наприклад, нехай є три можливих договору для фірми "АТС-50", якої потрібно партія кабелю АВВГ російського виробника обсягом 1000 одиниць за ціною 2 $ за одиницю в терміни не більше 18 днів:
№
Фірма
Товар
Виробник
мін. партія.
Кількість
Ціна
Терміни
4
Будсервіс
Кабель АВВГ
Іркутсккабель
900
9000
1
11
6
Все для дому
Кабель АВВГ
ММЗ
900
9000
1
12
12
Ункомтех
Кабель АВВГ
Іркутсккабель
700
1200
0.9
8
При застосуванні першого критерію вибираються фірми "Будсервіс" та "Все для дому", оскільки ціна, за якою вони пропонують товар, більше, ніж у фірми "Унікомтех" і отже дохід посередника буде більше. На другому етапі з цих двох фірм вибирається "Будсервіс", оскільки у неї менше термін поставки.
6. логічна модель подання знань на мові многосортного обчислення предикатів і мовою Пролог
Логічна модель - це опис предметної області на будь-якому логічному мовою. Одним з таких логічних мов є многосортное числення предикатів. При поданні логічних моделей на цій мові класи сутностей предметної області інтерпретуються, як імена сортів.
Для прикладу введемо наступні імена сортів: Договір, Постачальник, Покупець, Продукція, Виробник, Кількість, Ціна, Термін, Тіп_Проізв, а так само наступні функції і предикати:
пост: Договір Постачальник, покуп: Договір Покупець,
прод: Договір Продукція, произв: Договір Виробник,
кол: Договір Кількість, ціна: Договір Ціна, термін: Договір Термін
тіп_проізв: Виробник Тіп_Проізв
російський: Тіп_Проізв, європейський: Тіп_Проізв
: Кількість Кількість T
: Кількість Кількість T
Вирази 1-4 сотавляют сигнатуру і мають наступний зміст:
Визначає декілька функцій, наприклад прод (продукція), які будучи застосовні до об'єкта е b> сорти Договір, дають наприклад продукцію прод ( е b>), що бере участь в операції е b>.
Визначає функцію, значеннями якої служать типи виробника.
Визначає константи, що належать сорту Тіп_Проізв.
Визначає двомісні предикати на об'єктах сорти Кількість.
Сигнатура - це безліч функцій виду f: A1 A2 ... An B, де A1, A2, ..., An - аргументи, B - значення функції. Безліч аргументів і значень функцій утворюють відповідно сорти A і B. В окремому випадку, якщо B = T, причому T = (1,0) - особливий сорт, то сигнатура має вигляд P: A1 A2 ... An T, причому P називають предикатом.
Сигнатура задає структурні зв'язки між поняттями предметної області, представлені предикатами та функціями. Логіка зв'язку між цими поняттями задаються формулами, які записуються в сигнатурі. Структурні та логічні зв'язки виражають деяке знання про предметну область. Таким чином, сигнатура формально представляє одну частину знання про предметну область, а формули, записані в цій сигнатурі, мають іншу частину знання.
Графічне подання сигнатури показано на рис.4, а модельної структури - на рис.5.
Рис.4. Графічне подання сигнатури
Логічна модель в Пролозі представляється у вигляді предикатів і баз даних database. Наприклад:
database - договір
дог (Постачальник, Покупець)
Функцію пост (постачальник) можна реалізувати так
пост (N): - дог (Покупець, Постачальник), N = Постачальник.
Функцію можна подати так:
(Колічество1, Колічество2):-Колічество1P
P autoload: --
P makewindow (2,74,79, "ПОМИЛКА", 6,18,8,40),
P cursor (2,10),
P write ( "Ні бази на диску"),
P sound (70,294),
P removewindow,
P!.
P
P
P/* Головне меню * /
P
P main_menu: --
P repeat,
P cursor (7,0),
P write ( "0 - Про систему ..."), nl,
P write ( "1 - Коригування даних"), nl,
P write ( "2 - Знищення записів"), nl,
P write ( "3 - Перегляд баз даних"), nl,
P write ( "4 - Укладення договорів"), nl,
P write ( "5 - Інтерактивний режим"), nl,
P write ( "6 - Вихід з програми"), nl,
P write ( "=>"),
readint (C),
clearwindow,
working (C),
clearwindow,
C = 6,
retractall (_),
removewindow.
/* Висновок даних про творця програми * /
working (0): --
makewindow (3,27,30, "Про систему ...", 0,0,25,80),
nl, nl,
write ( "Інфоpмаціонно-спpавочная система"),
nl, nl,
write ( "Посередник"),
nl, nl, nl, nl,
write ( "Програма складена в середовищі"),
nl,
write ( "TURBO-PROLOG v.2.0."),
nl, nl, nl,
write ( "автоp: Данченко А.В."),
nl, nl,
write ( "МІРЕА, гp.ІІ-1-95 (С) 1997 р."),
nl,
sound (5,220),
cursor (22,26),
write ( "Натисніть на будь-яку клавішу"),
readchar (_),
removewindow,!.
/* Процедура виводу меню коректування даних * /
working (1): --
makewindow (4,26,48, "Коppектіровка даних", 0,0,25,80),
sound (5,220),
repeat,
nl,
nl,
cursor (9,0),
write ( "1 - Зміна даних по постачальникам"), nl,
write ( "2 - Зміна даних по покупцям"), nl,
write ( "3 - Додавання даних по постачальникам"), nl,
write ( "4 - Додавання даних по покупцям"), nl,
write ( "5 - Вихід в головне меню"), nl,
write ( "=>"),
readint (X),
clearwindow,
X> 0, X "),
readint (I),
clearwindow,
I> 0, I "),
readint (X),
clearwindow,
X> 0, X "),
readint (X),
clearwindow,
X> 0, X
P
P ok: --
P makewindow (17,27,90, "ОК", 6,18,8,40),
P cursor (2,7),
P write ( "Операцію виконали"), nl, nl,
P write ( "Натисніть на будь-яку клавішу"),
P readchar (_),
P removewindow.
P
P
P/* Процедура repeat * /
P
P repeat.
P repeat: - repeat.
P
P
P/* Процедура виявлення зв'язків по класифікує мережі * /
P
P cmp_name (Proizv, Proizv).
P cmp_name (Proizv, Proizv1): --
P find_web (Proizv, Proizv1).
P
P find_web (X, Y):-sup (X, Y).
P find_web (X, Y):-sup (X, Z), find_web (Z, Y).
P
P
P/* Процедура виявлення всіх можливих контрактів * /
P
P all_contract: --
P покупець (N, _, Tov, Proizv, Part, Price, Srok),
P постачальник (N1, _, Tov, Proizv1, Min1, Kol1, Price1, Srok1),
P cmp_name (Proizv, Proizv1),
P Part> = Min1, Part = Price1, Srok> = Srok1,
assertz (contract (N, N1)),
assert (best (N, 0,0,0)),
assert (best2 (N, 0,0,1000)),
fail.
all_contract:-print_contract.
/* Процедури виведення на екран всіх можливих контрактів * /
print_contract: --
makewindow (16,31,26, "Всі можливі контракти", 0,0,25,80),
nl, nl,
покупець (N, Firm ,_,_,_,_,_),
checkcontr (N),
prn (N, Firm),
fail.
print_contract: --
retractall (_, contract),
removewindow.
prn (N, Firm): --
cursor (1,1),
write ( "Для фірми:", Firm),
nl,
write ("|=========================================== ======================|"), nl,
write ( "| | | | | мін. | | | |"), nl,
write ( "| No | Фірма | Товар | Виробник | партія | Кількість | Ціна | Д |"), nl,
write ("|=========================================== ======================|"), nl,
contract (N, N1),
постачальник (N1, Firm1, Tov1, Proizv1, Min1, Kol1, Price1, Srok1),
cursor (Z, _),
cursor (Z, 1), write (N1),
cursor (Z, 3), write ("|", Firm1),
cursor (Z, 16), write ("|", Tov1),
cursor (Z, 36), write ("|", Proizv1),
cursor (Z, 50), write ("|", Min1),
cursor (Z, 59), write ("|", Kol1),
cursor (Z, 68), write ("|", Price1),
cursor (Z, 73), write ("|", Srok1),
cursor (Z, 0), write ("|"),
cursor (Z, 76), write ("|"),
nl,
покупець (N ,_,_,_, Part ,_,_),
retract (contract (N, N1)),
Cs = Part * Price1,
form_best (N, N1, Cs, Srok1),
form_best2 (N),
fail.
prn (N ,_):-
write ("|=========================================== ========================|"),
nl,
best2 (N, Np ,_,_),
постачальник (Np, Firm ,_,_,_,_,_,_), nl,
write ( "Найкращий"), nl,
write ( "контракт з фірмою:", Firm), nl,
cursor (22,26),
write ( "Натисніть на будь-яку клавішу"),
readchar (_),
clearwindow,!.
/* Перевіряє, чи є контракти * /
checkcontr (N):-contract (N, _).
/* Процедура формування найбільш пріоритетним контракту * /
form_best (N, Np, S, Srok): - Na = N,
best (Na, Np1, S1, Srok1), S = S1,
assertz (best (Na, Np, S, Srok )),!.
form_best (N, Np, S, Srok): - Na = N,
best (Na, Np1, S1, Srok1), S> S1, fb1 (Na, Np, S, Srok),
assertz (best (Na, Np, S, Srok )),!.
form_best (_,_,_,_).
fb1 (N ,_,_,_):-
retract (best (N ,_,_,_)), fail.
fb1 (_,_,_,_).
form_best2 (N): --
best (N, Np, S, Srok), f_b2 (N, Np, S, Srok), fail.
form_best2 (_).
f_b2 (N, Np, S, Srok): - Na = N,
best2 (Na, Np1, _, Srok1), Srok1> Srok,
fb2 (Na, Np, S, Srok),
assertz (best2 (Na, Np, S, Srok )),!.
f_b2 (_,_,_,_).
fb2 (N ,_,_,_):- retract (best2 (N ,_,_,_)), fail.
fb2 (_,_,_,_).
/* Процедури укладення договорів в інтерактивному режимі * /
interact (1): --
makewindow (9,26,48, "Пошук постачальника", 0,0,25,80),
nl,
write ( "Введіть назву фірми:"), readln (F),
write ( "Введіть назву товару:"), readln (T),
write ( "Введіть виробника:"), readln (P),
write ( "Введіть необхідну партію:"), readInt (M),
write ( "Введіть ціну за одиницю товару:"), readreal (Pr),
write ( "Введіть строки поставки:"), readInt (S), nl,
N = 0,
Firm = F, Tov = T, Proizv = P,
Part = M,
Price = Pr, Srok = S,
assertz (покупець (N, Firm, Tov, Proizv, Part, Price, Srok)),
removewindow,
постачальник (N1, _, Tov, Proizv1, Min1, Kol1, Price1, Srok1),
cmp_name (Proizv, Proizv1),
Part> = Min1, Part = Price1, Srok> = Srok1,
assert (flag (2)),
assertz (contract (N, N1)),
assert (best (N, 0,0,0)),
fail.
interact (1):-flag (2), print_contract,
retract (покупець (0, Firm, Tov, Proizv, Part, Price, Srok)),
retract (flag (2 )),!.
interact (1): --
warning (N),
покупець (0, Firm, Tov, Proizv, Part, Price, Srok),
assertz (покупець (N, Firm, Tov, Proizv, Part, Price, Srok)),
ins_sup (Proizv),
retract (покупець (0, Firm, Tov, Proizv, Part, Price, Srok)),
assert (flag (1)),
!.
interact (1): - retract (покупець (0, Firm, Tov, Proizv, Part, Price, Srok )),!.
interact (2): --
makewindow (9,26,48, "Пошук покупця", 0,0,25,80),
nl,
write ( "Введіть назву фірми:"), readln (F),
write ( "Введіть назву товару:"), readln (T),
write ( "Введіть виробника:"), readln (P),
write ( "Введіть мінімальну партію:"), readInt (M),
write ( "Введіть наявну партію:"), readInt (I),
write ( "Введіть ціну за одиницю товару:"), readreal (Pr),
write ( "Введіть строки поставки:"), readInt (S), nl,
N = 0,
Firm = F, Tov = T, Proizv = P, Min = M,
Kol = I,
Price = Pr, Srok = S,
assertz (постачальник (N, Firm, Tov, Proizv, Min, Kol, Price, Srok)),
removewindow,
покупець (N1, _, Tov, Proizv1, Part1, Price1, Srok1),
cmp_name (Proizv1, Proizv),
Part1> = Min, Part1 = Price, Srok1> = Srok,
assert (flag (2)),
assertz (contract (N1, N)),
assert (best (N1, 0,0,0)),
fail.
interact (2):-flag (2), print_contract,
retract (постачальник (0, Firm, Tov, Proizv, Min, Kol, Price, Srok)),
retract (flag (2 )),!.
interact (2): --
warning (N),
постачальник (0, Firm, Tov, Proizv, Min, Kol, Price, Srok),
assertz (постачальник (N, Firm, Tov, Proizv, Min, Kol, Price, Srok)),
ins_sup (Proizv),
retract (постачальник (0, Firm, Tov, Proizv, Min, Kol, Price, Srok)),
assert (flag (1)),
!.
interact (2): - retract (постачальник (0, Firm, Tov, Proizv, Min, Kol, Price, Srok )),!.
interact (_).
/* Висновок попередження про неможливість укладення договору * /
warning (N):-makewindow (7,49,113, "Попередження", 5,10,12,60),
sound (5,220), nl, nl,
write ( "На даний момент укладення контракту неможливо"), nl,
write ( "Помістити дані в базу даних"), nl,
write ( "для наступної обробки?"), nl, nl,
write ( "[Д] а/[Н] ет"), nl,
readchar (Ch),
removewindow,
Ch = 'Д',
write ( "Введіть порядковий номер фірми:"), readInt (N), nl,
!.
/* Видалення елемента з класифікує мережі * /
% У середині ланцюжка
del_sup (S): - sup (S, X), del_sup (X), fail.
% Наприкінці ланцюжка
del_sup (S): - sup (_, S), retract (sup (_, S)), fail.
del_sup (_).
/* Визначення необхідності додавання і додавання * /
/* елемента в що класифікують мережа * /
ins_sup (S):-sup (_, S),!.
ins_sup (S):-sup ( "виробник", S),!.
ins_sup (S): --
write ( "Введіть регіональну приналежність об'єкта _", S, "_:"),
readln (M), nl,
assertz (sup (M, S)), assert (flag (1)), ins_sup (M),!.
/* Вивід на друк зв'язків у класифікує мережі * /
view_sup (S): --
sup (S, M), write (S, "->", M), write ( ";"),
view_sup (M), nl, fail.
view_sup (_):- readchar (_).