Файл: КУРСОВАЯ ПО ТВП.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 22.08.2024

Просмотров: 43

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Министерство образования и науки Российской Федерации

Федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования «Магнитогорский государственный технический университет им. Г.И. Носова»

Кафедра вычислительной техники и прикладной математики

Курсовая работа

по дисциплине «Теория вычислительных процессов»

на тему «Семантика и семантические схемы программ. Задача об обедающих философах»

Выполнила:

студентка группы АВ-10,

Барханова Э.Р.

Проверила:

к.т.н, доцент,

Кочержинская Ю.В.

Магнитогорск

2013

Содержани

1 Теоретический вопрос «Семантика и семантические схемы программ» 3

1.1Операционная семантика 3

1.2Денотационная семантика 5

1.3Аксиоматическая семантика 8

1.4Трансляционная семантика 9

1.5Выводы по методам определения семантики 10

2 Задача о пяти обедающих философах 10

2.1 Постановка задачи 10

2.2 Решение задачи 11

2.3 Листинг процедур, обеспечивающих решение задачи 12

3 Список использованных источников 15

1 Теоретический вопрос «Семантика и семантические схемы программ»3

1.1 Операционная семантика3

1.2 Денотационная семантика5

1.3 Аксиоматическая семантика8

1.4 Трансляционная семантика9

1.5 Выводы по методам определения семантики9

2 Задача о пяти обедающих философах10

2.1 Постановка задачи10

2.2 Решение задачи10

2.3 Листинг процедур, обеспечивающих решение задачи11

3 Список использованных источников15


1 Теоретический вопрос «Семантика и семантические схемы программ»

В большинстве руководств определение семантики дается в виде обычного текста. Как правило, сначала при помощи какой-либо формальной грамматики дается определение синтаксиса конструкции, а затем для пояснения семантики приводятся несколько примеров и небольшой пояснительный текст. К сожалению, смысл этого текста часто неоднозначен, так что разные читатели могут понимать его по-разному. Программист может получить ошибочное представление о том, что именно будет делать написанная им программа при выполнении, а разработчик может реализовать какую-либо языковую конструкцию иначе, чем разработчики других реализаций того же языка. Как и для синтаксиса, нужен какой-то метод, позволяющий дать точное и лаконичное определение семантики языка.

Задача определения семантики языка программирования рассматривается теоретиками давно, но до сих пор не найдено удовлетворительного универсального решения. Было разработано множество различных методов формального определения семантики. Рассмотрим некоторые из них.

    1. Операционная семантика

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

Пусть состояние компьютера - это значения всех его регистров и ячеек памяти, в том числе коды условий и регистры состояний. Если просто записать состояние компьютера, выполнить команду, смысл которой нужно определить, а затем изучить новое состояние машины, то семантика этой команды станет понятной: она представляется изменением в состоянии компьютера, вызванным выполнением команды.

Описание операционной семантики операторов языков программирования высокого уровня требует создания реального или виртуального компьютера. Аппаратное обеспечение компьютера является чистым интерпретатором его машинного языка. Чистый интерпретатор любого языка программирования может быть создан с помощью программных средств, которые становятся виртуальным компьютером для данного языка. Семантику языка высокого уровня можно описать, используя чистый интерпретатор данного языка. При таком подходе, правда, существуют две проблемы. Во-первых, сложность и индивидуальные особенности аппаратного обеспечения компьютера и операционной системы, используемых для запуска чистого интерпретатора, затрудняют понимание происходящих действий. Во-вторых, выполненное таким образом семантическое определение будет доступно только для людей с абсолютно идентичной конфигурацией компьютера.


Этой проблемы можно избежать, заменив реальный компьютер виртуальным компьютером низкого уровня. Регистры, память, информация о состоянии и процесс выполнения операторов - все это можно смоделировать, соответствующими программами. Набор команд можно создать так, чтобы семантику каждой отдельной команды было легко понять и описать. Таким образом, машина была бы идеализирована и значительно упрощена, что облегчило бы понимание изменений ее состояния.

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

В таблице 1.1 представлен пример, в котором семантику конструкции forязыка С можно описать в терминах следующих простых команд.

Таблица 1.1 – Пример операционной семантики

Оператор языка С

Операционная семантика

for(expr1;expr2;ехрr3) { … }

expr1 loopif expr2 = 0 goto out … ехрr3; goto loop out:

Человек, читающий подобное описание, является «виртуальным компьютером» и предполагается способным правильно «выполнить» команды описания и распознать эффект такого «выполнения».

В качестве примера низкоуровневого языка, который можно применять для операционной семантики, рассмотрим следующий список операторов, представленный в таблице 1.2, соответствующих простым управляющим операторам типичного языка программирования.

Таблица 1.2 – Пример операционной семантики

Язык низкого уровня

Операционная семантика

ident := var ident := ident - 1

goto label if var relop var goto label

Здесь relop - одни из операторов отношений из набора {= , <>, >, <, >=, <=}, ident - идентификатор, a var - идентификатор или константа. Все эти операторы просты и легки для понимания и реализации.


Первым и самым значительным использованием формальной операционной семантики было описание семантики языка PL/I. Эта абстрактная машина и правила трансляции языка PL/I были названы общим именем Vienna Definition Language (VDL) в честь города, в котором они были созданы корпорацией IBM.

Операционная семантика является эффективной до тех пор, пока описание языка остается простым и неформальным. К сожалению, описание VDL языка PL/I настолько сложно, что практическим целям оно фактически не служит.

Операционная семантика зависит от алгоритмов, а не от математики. Операторы одного языка программирования описываются в терминах операторов другого языка программирования, имеющего более низкий уровень. Этот подход может привести к порочному кругу, когда концепции неявно выражаются через самих себя. Методы, описываемые в следующих двух разделах, значительно более формальны в том смысле, что они опираются на логику и математику, а не на машины.

    1. Денотационная семантика

Денотационная семантика - самый строгий широко известный метод описания значения программ. Она прочно опирается на теорию рекурсивных функций. Всестороннее рассмотрение денотационной семантики - длительное и сложное дело.

Основной концепцией денотационной семантики является определение для каждой сущности языка некоего математического объекта и некоей функции, отображающей экземпляры этой сущности в экземпляры этого математического объекта. Поскольку объекты определены строго, то они представляют собой точный смысл соответствующих сущностей. Сама идея основана на факте существования строгих методов оперирования математическими объектами, а не конструкциями языков программирования. Сложность использования этого метода заключается в создании объектов и функций отображения. Название метода «денотационная семантика» происходит от английского слова denote (обозначать), поскольку математический объект обозначает смысл соответствующей синтаксической сущности.

Для введения в денотационный метод мы используем очень простую языковую конструкцию – двоичные числа. Синтаксис этих чисел можно описать следующими грамматическими правилами:

<двоичное_число> → 0 | 1; | <двоичное_число> 0; | <двоичное_число> 1.


Для описания двоичных чисел с использованием денотационной семантики и грамматических правил, указанных выше, их фактическое значение связывается с каждым правилом, имеющим в своей правой части один терминальный (основной) символ. Объектами в данном случае являются десятичные числа.

В этом примере значащие объекты должны связываться с первыми двумя правилами. Остальные два правила являются, в известном смысле, правилами вычислений, поскольку они объединяют терминальный символ, с которым может ассоциироваться объект, с нетерминальным, который может представлять собой некоторую конструкцию.

Пусть область определения семантических значений объектов представляет собой множество неотрицательных десятичных целых чисел Nat. Это именно те объекты, которые мы хотим связать с двоичными числами. Семантическая функция Мb отображает синтаксические объекты в объекты множества N согласно указанным выше правилам. Сама функция Мb определяется следующим образом:

Мb('0') = 0, Мb('1')=1; Мb(<двоичное_число> '0') = 2 × Мb(<двоичное_число>); Мb(<двоичное_число> ‘1’) = + 2 × Мb(<двоичное_число>) + 1.

Мы заключили синтаксические цифры в апострофы, чтобы отличать их от математических цифр. Отношение между этими категориями подобно отношениям между цифрами в кодировке ASCII и математическими цифрами. Когда программа считывает число как строку, то прежде, чем это число сможет использоваться в программе, оно должно быть преобразовано в математическое число.

Описание значения десятичных синтаксических литеральных констант. <десятичное_число> → 0|1|2|3|4|5|6|7|8|9; | <десятичное_число> (0|1|2|3|4|5|6|7|8|9).

Денотационные отображения для этих синтаксических правил имеют следующий вид:

Md(‘0') = 0, Md('1') = 1, ,..., Md('9') = 9; Мd(<десятичное_число> '0') = 10 × Мd(<двоичное_число>); Мd(<десятичное_число> ‘1’) = 10 × Мd(<десятичное_число>) + 1; … Мd(<десятичное_число> '9') = 10 × Мd(<десятичное_число>) + 9.

После определения полной системы для заданного языка ее можно использовать для определения смысла полных программ этого языка. Это создает основу для очень строгого способа мышления в программировании.

Денотационную семантику программы можно определить в терминах изменений состояний идеального компьютера. Подобным образом определялись операционные ceмантики, приблизительно так же определяются и денотационные. Правда, для простоты они определяются только в терминах значений всех переменных, объявленных в программе. Операционная и денотационная семантики различаются тем, что изменения состояний в операционной семантике определяются запрограммированными алгоритмами, а в денотационной семантике они определяются строгими математическими функциями. Пусть состояние s программы определяется следующим набором упорядоченных пар: