0 / 0 / 0
Регистрация: 31.05.2011
Сообщений: 3

Гиперборейцы обсуждают вычислительную технику[Visual Prolog]

01.06.2011, 20:21. Показов 934. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. На Прологе мною была реализована следующая задача:

Гиперборея не оставалась в стороне от научно-технического прогресса. В стране появились счеты.
Однажды трое гиперборейцев решили обсудить новую вычислительную технику.
Известно, что один из этих троих – сорореанец, который всегда говорит правду, второй – норореанец, который всегда лжет, а третий – мидрореанец, который говорит правду и лжет через раз, но первый ответ может быть и правдой, и ложью. Вот что они говорили:

А: 1. В до сих пор считает по пальцам.
2. Б счеты очень нужны.
3 Я не норореанец.
Б: 1. Мне не нужны счеты.
2. Я – мидрореанец.
В: 1. А врет, что я считаю по пальцам.
2. Я – сорореанец.

Кто же из троих сорореанец, кто мидрореанец и кто норореанец?

Задача была реализована следующим образом:
Prolog
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
DOMAINS
 
герой = герой(имя,племя)
список_героев = герой*
имя,племя,свойство = symbol
список_племен = племя*
список_имен = имя*
да_нет = свойство*
номер = integer
 
PREDICATES
 
nondeterm один_из(имя,список_имен)
nondeterm один_из(племя,список_племен)
nondeterm один_из(свойство,да_нет)
    
% свойство1 = Б считает на счетах, свойство2 = В считает на пальцах
% свойство3 = Мидрореанец соврал в первый раз(да) или во второй раз(нет)
 
nondeterm сказал(герой,номер,свойство,свойство)
nondeterm гипотезы(список_героев,свойство,свойство)
nondeterm проверка(герой,номер,свойство,свойство,свойство)
nondeterm решение(список_героев)
    
CLAUSES
 
    один_из(X,[X|_]).
    один_из(X,[_|Y]):-один_из(X,Y).
    
    
    
%              А: 1. В до сих пор считает по пальцам.
%                   2. Б счеты очень нужны.
%                   3 Я не норореанец. 
    
    сказал(герой(а,_),1,_,да).
    сказал(герой(а,_),2,да,_).
    сказал(герой(а,Племя),3,_,_) :- not(Племя = "норореанец").
    
%              Б:  1. Мне не нужны счеты.
%                    2. Я - мидрореанец.    
        
    сказал(герой(б,_),1,нет,_).
    сказал(герой(б,мидрореанец),2,_,_).
    
%              В:  1. А врет, что я считаю по пальцам.
%                    2. Я - сорореанец.  
    
    сказал(герой(в,_),1,_,нет).
    сказал(герой(в,сорореанец),2,_,_).
    
    %ГЕНЕРАЦИЯ ГИПОТЕЗЫ
 
гипотезы(Герои,Б_на_счетах,В_на_пальцах):-
    
    Герои = [герой(а,Племя1),
            герой(б,Племя2),
                   герой(в,Племя3)],
                    
    один_из(Племя1,[сорореанец,мидрореанец,норореанец]),
        один_из(Племя2,[сорореанец,мидрореанец,норореанец]), not(Племя1 = Племя2),
            один_из(Племя3,[сорореанец,мидрореанец,норореанец]), not(Племя1 = Племя3), not(Племя2 = Племя3),
        
        один_из(Б_на_счетах,[да,нет]),
            один_из(В_на_пальцах,[да,нет]).
        
%       Известно, что один из этих троих - сорореанец, который всегда говорит правду,
%       второй - норореанец, который всегда лжет,
%       а третий - мидрореанец, который говорит правду и лжет через раз, но первый ответ может быть и правдой, и ложью.
        
    проверка(Герой,Номер,Б_на_счетах,В_на_пальцах,_) :-
        Герой = герой(_,сорореанец),
        сказал(Герой,Номер,Б_на_счетах,В_на_пальцах).
        
    проверка(Герой,Номер,Б_на_счетах,В_на_пальцах,Мидрореанец) :-
        Герой = герой(_,мидрореанец),
%Мидро соврал в первый раз, значит каждое нечетное высказывание ложно     
        Мидрореанец="да", 1 = Номер mod 2, 
        not(сказал(Герой,Номер,Б_на_счетах,В_на_пальцах)).
    проверка(Герой,Номер,Б_на_счетах,В_на_пальцах,Мидрореанец) :-
        Герой = герой(_,мидрореанец),
%Мидро соврал в первый раз, значит каждое четное высказывание истинно
        Мидрореанец="да", 0 = Номер mod 2,
        сказал(Герой,Номер,Б_на_счетах,В_на_пальцах).
    проверка(Герой,Номер,Б_на_счетах,В_на_пальцах,Мидрореанец) :-
        Герой = герой(_,мидрореанец),
%Мидро соврал во второй раз, значит каждое четное высказывание ложно
        Мидрореанец="нет", 0 = Номер mod 2, 
        not(сказал(Герой,Номер,Б_на_счетах,В_на_пальцах)).
    проверка(Герой,Номер,Б_на_счетах,В_на_пальцах,Мидрореанец) :-
        Герой = герой(_,мидрореанец),
%Мидро соврал во второй раз, значит каждое нечетное высказывание истинно
        Мидрореанец="нет", 1 = Номер mod 2,
        сказал(Герой,Номер,Б_на_счетах,В_на_пальцах).
 
    проверка(Герой,Номер,Б_на_счетах,В_на_пальцах,_) :-
        Герой = герой(_,норореанец),
        not(сказал(Герой,Номер,Б_на_счетах,В_на_пальцах)).
        
%РЕШЕНИЕ
        
решение(Герой):-
    гипотезы(Герой,Б_на_счетах,В_на_пальцах),
    Герой = [А,Б,В],
    один_из(Мидрореанец_соврал_в_первый_раз,[да,нет]),
        
    проверка(А,1,Б_на_счетах,В_на_пальцах,Мидрореанец_соврал_в_первый_раз),
        проверка(А,2,Б_на_счетах,В_на_пальцах,Мидрореанец_соврал_в_первый_раз),
            проверка(А,3,Б_на_счетах,В_на_пальцах,Мидрореанец_соврал_в_первый_раз),
 
    проверка(Б,1,Б_на_счетах,В_на_пальцах,Мидрореанец_соврал_в_первый_раз),
        проверка(Б,2,Б_на_счетах,В_на_пальцах,Мидрореанец_соврал_в_первый_раз),
 
    проверка(В,1,Б_на_счетах,В_на_пальцах,Мидрореанец_соврал_в_первый_раз),
        проверка(В,2,Б_на_счетах,В_на_пальцах,Мидрореанец_соврал_в_первый_раз).
        
GOAL
 
    решение(Герой).
Программа прекрасно работает и выдает правильный ответ.
Однако преподаватель сказал, что она нечитаема.Попросил исправить внешний вид программы, оставив структуру. А именно, попросил исправить формулировку высказываний:

Prolog
1
2
3
4
5
6
7
8
9
10
11
12
    
    сказал(герой(а,_),1,_,да).
    сказал(герой(а,_),2,да,_).
    сказал(герой(а,Племя),3,_,_) :- not(Племя = "норореанец").
        
        
    сказал(герой(б,_),1,нет,_).
    сказал(герой(б,мидрореанец),2,_,_).
        
    
    сказал(герой(в,_),1,_,нет).
    сказал(герой(в,сорореанец),2,_,_).
Изменить так,чтобы было понятно,кто,о ком и о чем говорит.

А также убрать свойство
% свойство1 = Б считает на счетах, свойство2 = В считает на пальцах.

Я исправила,и вот что у меня получилось:

Prolog
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
DOMAINS
 
герой = герой(имя,племя)
список_героев = герой*
имя,племя,способ_счета,свойство = symbol
список_способов_счета=способ_счета*
список_племен = племя*
список_имен = имя*
да_нет = свойство*
номер = integer
итог = список_героев*
 
PREDICATES
 
nondeterm один_из(имя,список_имен)
nondeterm один_из(племя,список_племен)
nondeterm один_из(способ_счета,список_способов_счета)
nondeterm один_из(свойство,да_нет)
    
% свойство1 = Б считает на счетах, свойство2 = В считает на пальцах
% свойство3 = Мидрореанец соврал в первый раз(да) или во второй раз(нет)
 
nondeterm сказал(герой,номер,герой,способ_счета)
nondeterm гипотезы(список_героев,способ_счета)
nondeterm проверка(герой,номер,герой,способ_счета,свойство)
nondeterm решение(список_героев)
%nondeterm является(имя,имя,имя,герой)
CLAUSES
 
    один_из(X,[X|_]).
    один_из(X,[_|Y]):-один_из(X,Y).
    
    
    
%              А: 1. В до сих пор считает по пальцам.
%                   2. Б счеты очень нужны.
%                   3 Я не норореанец. 
    
    сказал(герой(а,_),1,герой(в,_),на_пальцах).
    сказал(герой(а,_),2,герой(б,_),на_счетах).
    сказал(герой(а,Племя_а),3,герой(а,_),_) :- not(Племя_а = "норореанец").
    
%              Б:  1. Мне не нужны счеты.
%                    2. Я - мидрореанец.    
        
    сказал(герой(б,_),1,герой(б,_),на_пальцах).
    сказал(герой(б,Племя_б),2,герой(б,_),_):-Племя_б="мидрореанец".
    
%              В:  1. А врет, что я считаю по пальцам.
%                    2. Я - сорореанец.  
    
    сказал(герой(в,_),1,герой(в,_),на_счетах).
    сказал(герой(в,Племя_в),2,герой(б,_),_):-Племя_в="сорореанец".
    
    %ГЕНЕРАЦИЯ ГИПОТЕЗЫ
 
гипотезы(Герои,Способ_счета):-
    
    Герои = [герой(а,Племя1),
            герой(б,Племя2),
                   герой(в,Племя3)],
                    
    один_из(Племя1,[сорореанец,мидрореанец,норореанец]),
        один_из(Племя2,[сорореанец,мидрореанец,норореанец]), not(Племя1 = Племя2),
            один_из(Племя3,[сорореанец,мидрореанец,норореанец]), not(Племя1 = Племя3), not(Племя2 = Племя3),
        
        один_из(Способ_счета,[на_пальцах,на_счетах]).
        
%       Известно, что один из этих троих - сорореанец, который всегда говорит правду,
%       второй - норореанец, который всегда лжет,
%       а третий - мидрореанец, который говорит правду и лжет через раз, но первый ответ может быть и правдой, и ложью.
        
    проверка(Герой1,Номер,_,Способ_счета,_) :-
        Герой1 = герой(_,сорореанец),
        сказал(Герой1,Номер,Герой2,Способ_счета).
        
    проверка(Герой1,Номер,_,Способ_счета,Мидрореанец) :-
        Герой1 = герой(_,мидрореанец),
%       является(а,б,в,Герой)
        Герой2 = герой(а,_);
        Герой2 = герой(б,_);
        Герой2 = герой(в,_),
%Мидро соврал в первый раз, значит каждое нечетное высказывание ложно     
        Мидрореанец="да", 1 = Номер mod 2, 
        not(сказал(Герой1,Номер,Герой2,Способ_счета)).
    проверка(Герой1,Номер,_,Способ_счета,Мидрореанец) :-
        Герой1 = герой(_,мидрореанец),
%Мидро соврал в первый раз, значит каждое четное высказывание истинно
        Мидрореанец="да", 0 = Номер mod 2,
        сказал(Герой1,Номер,Герой2,Способ_счета).
    проверка(Герой1,Номер,_,Способ_счета,Мидрореанец) :-
        Герой1 = герой(_,мидрореанец),
        Герой2 = герой(а,_);
        Герой2=герой(б,_);
        Герой2=герой(в,_),
%Мидро соврал во второй раз, значит каждое четное высказывание ложно
        Мидрореанец="нет", 0 = Номер mod 2, 
        not(сказал(Герой1,Номер,Герой2,Способ_счета)).
    проверка(Герой1,Номер,_,Способ_счета,Мидрореанец) :-
        Герой1 = герой(_,мидрореанец),
%Мидро соврал во второй раз, значит каждое нечетное высказывание истинно
        Мидрореанец="нет", 1 = Номер mod 2,
        сказал(Герой1,Номер,Герой2,Способ_счета).
 
    проверка(Герой1,Номер,_,Способ_счета,_) :-
        Герой1 = герой(_,норореанец),
        
        Герой2 = герой(а,_);
        Герой2 = герой(б,_);
        Герой2 = герой(в,_),
        not(сказал(Герой1,Номер,Герой2,Способ_счета)).
    
%РЕШЕНИЕ
        
решение(Герой):-
    гипотезы(Герой,Способ_счета),
    Герой = [А,Б,В],
    один_из(Мидрореанец_соврал_в_первый_раз,[да,нет]),
        
    проверка(А,1,герой(в,_),Способ_счета,Мидрореанец_соврал_в_первый_раз),
        проверка(А,2,герой(б,_),Способ_счета,Мидрореанец_соврал_в_первый_раз),
            проверка(А,3,герой(а,_),Способ_счета,Мидрореанец_соврал_в_первый_раз),
 
    проверка(Б,1,герой(б,_),Способ_счета,Мидрореанец_соврал_в_первый_раз),
        проверка(Б,2,герой(б,_),Способ_счета,Мидрореанец_соврал_в_первый_раз),
 
    проверка(В,1,герой(в,_),Способ_счета,Мидрореанец_соврал_в_первый_раз),
        проверка(В,2,герой(в,_),Способ_счета,Мидрореанец_соврал_в_первый_раз).
        
 
        
        
GOAL
 
решение(Герой).
Программа перестала работать.Она выдает огромный список решений.
На первый взгляд она просто повторяет правильное. Но это не так. Она выводит правильно 700 с чем то раз, а потом так же много раз выводит все остальные возможные(проверялось с помощью findall и вывода уникальных).

Помогите найти ошибку во второй, или исправить первую под требования преподавателя!!!
Всю голову уже сломала. А не решение этой задачи грозит суммой в 7000р. или отчислением из института.

Добавлено через 20 часов 42 минуты
Неужели никто не может помочь???????
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.06.2011, 20:21
Ответы с готовыми решениями:

Перенос программы с Visual Prolog 7.1 в Visual Prolog 7.5
Проблема переноса. Взяла пример с книги Visual Prolog 7.1 для начинающих. Это игра червь. Вроде всё, что не компилировалось я исправила, но...

Из Turbo Prolog в Visual Prolog - где будут отличия в коде?
ребята ,помогите. есть прога на турбо прологе,а нужно отредактировать под visual prolog 7.5. Что изменится? Где отличия?.. ниже...

Пожалуйста, помоите переделать программу с Turbo Prolog на Visual Prolog
DOMAINS l_i=integer* l_s=string* i=integer s=string c=char structura=str(i,s) %Структура Порода-Параметры и его список ...

2
 Аватар для emppu2007
92 / 92 / 6
Регистрация: 04.05.2011
Сообщений: 171
01.06.2011, 20:52
Блин, вот извини пожалуйста, но лень копаться в столь объёмной проге [это не платный раздел{rrrFer}].
На твоём месте, я бы забил и просто поставил отсечение во втором варианте программы в конце процедуры "решение"...
0
0 / 0 / 0
Регистрация: 31.05.2011
Сообщений: 3
01.06.2011, 21:04  [ТС]
Хех,я то забила бы,но вот преподаватель не принимает программу с отсечением при выводе ответа. Да и вообще с точки решения подобной задачи ставить отсечение после решения не верно, ведь если выйдет правильный ответ, то это еще не значит, что программа рабочая.
 Комментарий модератора 
Не надо называть форумчан дураками
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.06.2011, 21:04
Помогаю со студенческими работами здесь

Перевести код из turbo prolog в visual prolog
не подскажите плиз как будет выглядеть код turbo prolog в Visual Prologe 7.3 turbo prolog: predicates for(integer,integer) ...

Код Turbo Prolog переделать в Visual Prolog 5.2
Помогите пожалуйста переделать код Turbo Prolog в Visual Prolog 5.2 domains st=st(string,real,real,real,real) st1=st1(string,real) ...

Перевести код из turbo prolog в visual prolog
не подскажите плиз как будет выглядеть код turbo prolog в Visual Prologe 5.2 turbo prolog: domains int=integer intl=int* ...

[Turbo Prolog] [Visual Prolog] Задача на рекурсию
Здравствуйте, помогите, пожалуйста, с такой задачей... Имеется горсть из N Монет C1,C2,....,Cn различного достоинства. Определить,...

С чего начать обучение, если хочешь поступать на Программную инженерию и Информатику и вычислительную технику
Учусь в десятом классе. До декабря 18 года собиралась поступать в мед, но передумала. На этот раз мой выбор пал на ИТ. В моем городе как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru