Prolog урок 4. Цели с подцелями

Цель урока: рассмотреть примеры создания баз данных со сложными целями (цели с подцелями)

Цели с подцелями в Prolog

Для начала вспомним, что:

Цели, требующие логический ответ (правда или ложь), записываются в окне Dialog (тогда раздел goal в программе не пишется)

Рассмотрим пример использования цели с подцелями в окне Dialog.
Допустим, в программе присутствуют следующие факты:

...
clauses 
 	likes (mary,apples). /* Мэри любит яблоки */
 	color(apples,red).  /* Яблоки красного цвета */

Для того, чтобы написать запрос:
«Любит ли Мэри яблоки, и красные ли эти яблоки?»

В окне Dialog необходимо набрать:

likes(mary,apples),color(apples,red).
  • Подцели разделены запятыми, точка завершает цель как целое.
  • Если одна из подцелей ложна, то вся цель является неуспешной. Если все подцели истинны, то вся цель является успешной.
  • Задание Prolog 4_1: Протестируйте программу, составив объявление и базу фактов. Составить запрос в окне Dialog

    Правила с несколькими предпосылками. Логические операции OR и AND

    Допустим, в программе присутствуют следующие факты:

    ...
    clauses 
     	wife(ivan,mary). /* Жена */
     	husband(mary,john).  /* Муж */
            married(ivan,mary).  /* Женаты */

    Для того, чтобы написать правило:
    «Джон и Мэри женаты, если Мэри жена Джона и если Джон муж Мэри»

    Добавим код:

    married(john,mary) if
    		wife(john,mary) 
    		and husband(mary,john).
    Важно:

    • Вместо if можно использовать :-
    • Вместо and можно использовать запятую
    • Точка с запятой ; используется для представления связки or (или)

    Усложним программу предыдущего урока про возраст и пол детей:

    * Пример: Составить базу данных, определяющую возраст и пол детей. Составить правило Школьник: школьником является ребенок, возраст которого больше 6 лет

    Выполнение:

    domains
     	a=symbol
    	b=integer
    predicates
    	pol(a,a)
    	vozrast (a,b)
            shkolnik(a)
    clauses 
    	pol(ivan,boy).
    	pol(sergey,boy).
    	pol(mary,girl).
     	vozrast(ivan,3).
     	vozrast(sergey,4).
     	vozrast(mary,5).
          shkolnik(X):-vozrast(X,Y),Y>6.
    goal
        shkolnik(X),write("shkolnik - ",X),nl, fail.
    * Задание Prolog 4_1: Составить базу фактов жен и мужей: в существующий код добавить несколько мужей и жен. Создать запросы через окно dialog к базе данных:

    1. женаты ли Иван и Мэри
    2. как зовут мужа Мэри
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    domains
     	a=symbol
    predicates
    	wife (a,a)
     	husband(a,a)
     	married(a,a)
    clauses 
     	wife (ivan,mary).
     	…
     	husband (mary, ivan).
     /*  
    окно dialog:
     		….
    */
    * Задание Prolog 4_2:
    Составить базу фактов по басне Крылова «Лебедь, рак и щука». Добавить правило, описывающее условие, при котором «воз и ныне там» (т.е. все три условия басни соблюдены).

    Запросы:

    1. Кто рвется в облака?
    2. Когда и что где «находится»?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    domains
      a=symbol
    predicates
      рвется(a,a).
      пятится(a,a).
      тянет(a,a).
      находится(a,a,a).
    Clauses
      рвется(лебедь,в_облака).
      пятится(рак,назад).
      тянет(щука,в_воду).
      находится(Воз,Ныне,Там):- ____________,
    ____________,
    ____________. 
    Goal
      /*  ... , write(...),nl,fail. */
    * Задание Prolog 4_3:
    Составить базу данных «Планеты». Добавить правило, определяющее понятие «спутник». Определить название спутников и название звезды, вокруг которой вращаются планеты.

    Запросы:

    1. Вывести все спутники всех планет
    2. Вывести название звезды вокруг которой вращаются Марс, Земля и Меркурий
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    domains
    	a=symbol
    predicates
    	звезда(a)
    	планета(a)
    	вращается(a,a)
    	спутник(a,a)
    clauses
    	звезда(солнце).
    	планета(земля).
    	планета(марс).
    	вращается(меркурий, солнце).
    	вращается(земля, солнце).
    	вращается(марс, солнце).
    	вращается(луна, земля).
    	вращается(фобос, марс).
    	вращается(деймос, марс).
    спутник(X,Y):-__________, _________.
     /*  
    окно dialog:
     		….
    */
    * Задание Prolog 4_4:
    Составить базу фактов по басне Крылова «Квартет». Составить правило, описывающее понятие «квартет». Составьте вопросы, например: кто играет на скрипке? На каком инструменте играет мишка? В каком случае возможен квартет?

    Запросы:

    1. Кто играет на скрипке?
    2. На каком инструменте играет мишка?
    3. В каком случае возможен квартет?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    domains
             a=symbol
    predicates
    играет(a,a).
    квартет(a,a,a,a).
    clauses
    играет(мартышка, скрипка).
    играет(осел, альт).
    играет(козел, скрипка).
    играет(мишка, бас).
    квартет(X1,X2,X3,X4):- играет(X1,скрипка),
    ____________,
    ____________,
    ____________.
    * Задание Prolog 4_5:

    Создать правило для отношения музыкант, используя утверждение: некто является музыкантом, если он обладает музыкальным слухом, и играет на музыкальном инструменте. Создайте запросы.

    Запросы:

    1. кто является музыкантом?
    2. на чем играет Иван?
    3. кто играет на фортепиано?
    4. у кого нет музыкального слуха
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    domains 
      a=symbol
    predicates
      играет(a,a)
      музыкальный_слух(a,a)
      музыкант(a)
    clauses
      играет(иван,на_скрипке).
      играет(ольга,на_фортепиано).
      играет(света,на_ фортепиано).
      играет(борис,на_гитаре).
      музыкальный_слух(иван, есть).
      музыкальный_слух(ольга, есть).
      музыкальный_слух(света, нет).
      музыкальный_слух(борис, нет).
    музыкант(X):-______________,   ___________________.
    * Задание Prolog 4_6:
    Составить базу фактов, содержащую оценки, полученные учениками по различным предметам. Определить, кто является отличником, кто неуспевающий, кто математик (создать правила).

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    domains
     a=symbol
     b=integer
    predicates
     оценка(a,a,b)
     отличник(a)
     неуспевающий(a)
     математик(a)
    clauses
     …
    Самостоятельная работа № 1:
    1 вариант:
    Составить базу данных «Реки России», содержащую название реки и ее протяженность (в км). С помощью правила определить какие из указанных рек можно считать маленькими (меньше 1000 км). Составить 3 запроса.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    domains
     a=symbol
     b=integer
    predicates
     река(a,b)
     маленькая_река(a)
    clauses
     река(амур, 4416).
     река(иртыш, 4248).
     река(волга, 3530).
     река(дон,2200).
     река(ангара,1880).
     река(кубань, 870).
     река(нева, 74).
    маленькая_река(X):- _______, _______.

    2 вариант:
    Заданы факты о книгах, их авторах и количестве страниц. Составьте базу знаний «Книги». Определите правилом, какой роман можно считать большим (более 300 страниц). Составить 3 запроса.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    domains
     заглавие, автор = symbol
     страниц = integer
    predicates
     книга(заглавие,страниц)
     написал(автор,заглавие)
     большой_роман(заглавие)
    clauses
     написал(тургенев,"Отцы и дети").
     написал(шолохов,"Тихий дон").
     написал(горький,"Мать").
     книга("Отцы и дети", 190).
     книга("Тихий дон",1250).
     книга("Мать",310).
    большой_роман(Заглавие):-  ____________, ____________, _________.

    * Задание Prolog 4_7:
    Составить базу знаний «Воинская служба». Определить, кто из молодых людей подлежит призыву (молодые люди 18 лет)? Кто не подлежит призыву (девушки, молодые люди младше 18)? Выполнить соответствующие запросы.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    domains
     a=symbol
     b=integer
    predicates
     мужчина(a)
     женщина(a)
     возраст(a,b)
     подлежит_призыву(a)
     не_подлежит(a)
    clauses
     возраст(борис,18).
     возраст(андрей,17).
     возраст(михаил,18).
     возраст(анна,18).
     возраст(юля,17).
     мужчина(борис).
     мужчина(андрей).
     мужчина(михаил).
     женщина(анна).
     женщина(юля).
    подлежит_призыву(X):-________,_________, ____.
    не_подлежит(X):-____________,__________ or ____________.
    Обратите внимание на использование логического оператора or (ИЛИ).

    * Пример: Необходимо создать базу данных, содержащую информацию о пациентах поликлиники. Заполнить факты. Создать правило поиска пациента по участку (с несколькими предпосылками)

    Выполнение:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    domains
    	name=string
    	street=string
    	dom=symbol
    	kvartira=integer
    	number=integer
     
    predicates
    	pacient(name,street,dom,kvartira)
    	uchastok(street,number)
    	poisk_po_uchastku(name,street,number)
    clauses
    	pacient("Ivanov","Sadovaya", "25", 78).
    	pacient("Stepanova","Suvorova", "10", 35).
    	pacient("Orlova","Moskovskaya", "16", 12).
    	uchastok("Suvorova",4).
    	uchastok("Sadovaya",2).
    	uchastok("Moskovskaya",6).
    	poisk_po_uchastku(X,Y,Z):-pacient(X,Y,_,_),uchastok(Y,Z).
    goal
    /* вывод всех пациентов с названиями улиц и номером участка */
    poisk_po_uchastku(X,Y,Z),write(X, " na ulitse ", Y, " ucastok ", Z),nl,fail.
    Важно:
    При составлении правил, вместо «ненужного» для правила аргумента необходимо записывать символ подчеркивания, как в рассмотренном примере:

    poisk_po_uchastku(X,Y,Z):-pacient(X,Y,_,_),uchastok(Y,Z).
    * Задание Prolog 4_8: Для рассмотренного выше примера базы данных пациентов составить запросы:

    1. К какому участку относится улица Садовая?
    2. Кто из пациентов проживает на улице Садовая?
    3. Кто из пациентов относится к четвертому участку?
    4. Кто из пациентов проживает по улице «Московская» и относится к участку № 6?

    Работа с бесконечным циклом Fail. Вывод конкретных значений

    * Пример: Имеется база фактов, содержащая названия некоторых стран. Необходимо выдать их на экран в той же последовательности.

    Выполнение:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    domains
       	a=symbol
    predicates
       	страна(a)
       	печать_стран
    clauses
       	страна(россия).
       	страна(англия).
       	страна(франция).
       	страна(германия).
    	печать_стран:- страна(X), write(X),
                      nl,  /*переход на новую строку*/
                      fail. /*инициализация возврата*/
    goal
    	печать_стран.

    Ключевым моментом в этой программе является печать всех стран. Чтобы вывести их в том же порядке, необходимо создать правило:

    Правило печати всех значений:

    печать_стран:- страна(X), X=франция, write(X)...
    * Задание Prolog 4_9: Опираясь на сведения, изложенные в рассмотренном примере, составить программу, формирующую список учеников. Выбрать и вывести на экран имя Алиса столько раз, сколько раз оно встречается в базе данных

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    domains
      	имя=symbol
    predicates
      ученик(имя)
      выбрать
    clauses
      ученик("Егор").
      ученик("Алиса").
      ученик("Иван").
      ученик("Петр").
      ученик("Алиса").
      …
      выбрать: –  ….
    goal
      	... .

    Родственные отношения

    * Задание Prolog 4_10:
    Составить программу «Семья». Маму Екатерины зовут Мария, а отца — Иван. У Екатерины есть дочь Елена, которая вышла замуж за Олега, и у них родился сын Сергей.

    Требуется:
    1) определить имена бабушек и дедушек в данной семье;
    2) назвать имена матерей и отцов;
    3) назвать имена всех мужчин в этой семье.

    Заполните пропущенные места в листинге программы:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    domains
      а=symbol
    predicates
      родитель(а,а)
      пол(а,а)
      мать(а,а)
      отец(а,а)
      дочь(а,а)
      сын(а,а)  
      бабушка(а,а)
      дедушка(а,а)
    clauses
      родитель(иван,екатерина).
      родитель(мария,екатерина).
      родитель(екатерина,елена).
      родитель(?,?).
      родитель(?,?).
      пол(иван,мужской).
      пол(мария,женщина).
      пол(екатерина,женщина).
      пол(?,?).
      пол(?,?).
      пол(?,?).
      мать(Х,Y):-родитель(?,?),пол(?,?).
      отец(Х,Y):-родитель(?,?),пол(?,?).
      дочь(X,Y):-родитель(?,?),пол(?,?).
      сын(Х,Y):-родитель(?,?),пол(?,?).
      бабушка(Х,Y):-пол(?,?), родитель(?,?),  родитель(?,?).
      дедушка(Х,Y):-пол(?,?), родитель(?,?),  родитель(?,?).

    Важно: Внутри определения правила может быть использовано другое правило. Так, в примере ниже, в определении правила кто_чья_сестра используется другое правило сестра(a,a)
    * Пример:
    В программе «Родственники» составить правило, определяющее отношение «быть сестрой».

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    domains
       a=symbol
    predicates
       мужчина(a)
       женщина(a)
       родители(a,a,a)  			/*(ребенок, отец, мать)*/
       сестра(a,a)      			/* (сестра, брат)*/
       кто_чья_сестра
    goal
       кто_чья_сестра.
    clauses
       мужчина(федор).
       мужчина(семен).
       женщина(маша).
       женщина(даша).
       родители(семен,федор,маша).
       родители(даша,федор,маша).
       кто_чья_сестра:- сестра(Сестра, Брат), 
             write(Сестра, " является сестрой ", Брат), nl.
       сестра(Сестра,Брат):- женщина(Сестра), родители(Сестра,Отец,Мать),
             родители(Брат,Отец,Мать).
    * Самостоятельная работа № 2:
    Составить базу знаний «Родственники по мужской линии». Определить отношения сын, дедушка, внук, брат, дядя, племянник, кузен (создать правила). Выполнить всевозможные запросы.

    Примечания:
    1. В разделе clauses данной задачи необходимо использовать факт отец(a,a), другие факты самостоятельно придумывать не надо.
    2. В правилах можно использовать другие правила.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    domains
       a=symbol
    predicates
       отец(a,a).   
       сын(a,a).
       дедушка(a,a).
       внук(a,a).
       брат(a,a).
       дядя(a,a).
       племянник(a,a).
       кузен(a,a).
    clauses
    отец(степан,андрей).
    …
     сын(X,Y):-???.
     дедушка(X,Y):-???.

    * При использовании материалов обязательна ссылка на источник: Кузнецова Т.К., «Программирование Turbo Prolog» — Задачи и решения, Ростов-на-Дону, ПИ ЮФУ — 2011г.