ВВЕДЕНИЕ

ЛЕКЦИЯ 1.

Юстиция Франции.

Общие и АС.

1. Суд большой юрисдикции.

2. Суд 1 инстанции.

3. Коммерческий суд.

4. Суд по трудовым спорам.

5. Суд по социальным вопросам.

6. Суд по делам несовершеннолетних.

7. Местный суд.

8. Полицейский суд.

9. Уголовный суд.

10. Суд ассизов.

8, 9, 10 – уголовные дела.

1, 2, 3, 4, 5 – гражданские дела.

6, 7 – гражданские и уголовные дела.

1 – 9. Второе звено – апелляционный суд.

10. Второе звено – апелляционный суд ассизов.

Высшее звено – кассационный суд.

АС. Нижнее звено – административные трибуналы. Второе звено – административный апелляционный суд. Третье звено – Государственный совет.

Другие административные суды, чьи решения подлежат контролю со стороны государственного совета.

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

Суд ассизов. Непостоянный, обычно каждые 3 месяца на 2 недели. 3 судьи и 9 присяжных – единая коллегия. Самые сложные дела.

 

о

о

В широком смысле слова программа – это последовательность инструкций или, иначе, команд. В соответствии с определением, программами являются музыкальные партитуры, узоры для вязания, технологические карты обработки деталей и многое другое. В этом смысле программы существовали задолго до появления Электронных Вычислительных Машин (ЭВМ). Естественно, что особенности процесса разработки или конструирования программ (программирования) существенно зависят от предметной области, но все программы имеют некоторые общие свойства:

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

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

3.В связи с тем, что автором программы обычно является человек и для него может оказаться несвойственным язык процессора, возникают проблемы, связанные с “переводом”. Такой перевод может оказаться достаточно сложным и выполняться автоматически с помощью некоторого устройства или программы (то и другое обычно называют транслятором).

4.Выполнение программы должно рассматриваться как процесс. Иными словами, сам «текст» программы есть нечто статическое, а процесс ее выполнения должен рассматриваться во времени. Обычно команды выполняются последовательно. Если не оговорено иначе, процесс начинается с первой команды и продолжается до тех пор, пока не выполнится вся программа. При этом последовательность в некоторых случаях может изменяться, например, при ветвлении (в связи с выполнением определенных условий) или необходимости повторения некоторых действий. Возможно также параллельное выполнение отдельных независимых участков программы при наличии дополнительных свободных процессоров. Здесь же можно упомянуть о конвейерном выполнении инструкций, когда инструкции выполняется, последовательно передаваясь от одного процессора к другому, но в одно и то же время в «обработке» могут находиться инструкции, количество которых не превышает числа имеющихся процессоров. При любом порядке выполнения инструкций, процесс должен обязательно завершаться.

5.Программа оперирует с некоторыми объектами. Например, для музыкальных партитур это звуки, закодированные с помощью нотных знаков, для технологических карт – детали или их заготовки, а для ЭВМ это числовые данные.

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

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

Текст программы или её фрагментов часто называют кодом. Таким образом, авторский вариант программы можно называть исходным кодом, а процессорный – машинным или исполняемым кодом. При этом вместо термина транслятор часто используют термины компилятор или интерпретатор, которые уточняют способ «перевода» исходного кода в машинный и способ выполнения машинного кода. Сам процесс «перевода» принято называть соответственно трансляцией, компиляцией или интерпретацией.

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

На рисунке (Рис.1) показана структура такой машины. Ее процессором является ЭВМ, которая используется дважды. На первом этапе (фаза трансляции) программа, выполняемая ЭВМ – это транслятор, а исходные данные – текст программы на языке высокого уровня. Результатом будет перевод такой программы в исполняемую программу или так называемый машинный код. Далее ЭВМ будет выполнять машинный код (фаза времени выполнения – run time, голубые стрелки). Исходными данными здесь послужат исходные данные самой задачи, а результатом – данные, определяющие ее решение.

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

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

2.Ошибки, обнаруживаемые при выполнении машинного кода. Такие ошибки могут возникать, например, при делении на нуль, попытке извлечь квадратный корень из отрицательного числа и т.п. Такой тип ошибок называется ошибками времени выполнения (run time error).

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

Однако ошибки могут быть не только в программе, они могут появляться и в исходных данных. Примером таких ошибок является ввод значения переменной x вместо y или числа 5 вместо числа 15.

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

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

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

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

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

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

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

Метод последовательных уточненийформально определяется следующим образом.Как уже упоминалось, программирование есть процесс разработки или проектирования программ, т.е. является объектом проектирования. В общем случае, любой объект проектирования (ОП) может быть представлен трехкомпонентным множеством вида ОП={F,S,Р} где F, S иР - соответственно функциональное структурное и параметрическое описания объекта.

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

Если объект с заданным F-описанием существует и удовлетворяет некоторым требованиям, связанным с оценкой его качества (параметрическому описанию), то задачу проектирования решать не имеет смысла. В противном случае такой объект необходимо проектировать. В процессе проектирования обычно используются прием, связанный с декомпозицией исходного F-описания на некоторые составляющие Fi, такие, что F=S(Fi), i=1,2, ...,n, где S - оператор, определяя композицию Fi, которая обеспечивает исходное F-описание. Таким образом, S-оператор (структурное описание) задает структуру ОП на рассматриваемом уровне детализации.

 

В связи с S-описанием обычно используется термин “структурирование”, который имеет двоякий смысл. Это либо процесс декомпозиции с целью выбора компонент, либо определение самого S-описания, т.е. конкретной формы объединения компонент, иными словами - композиция. Выбор альтернативы обычно определяется контекстом.

Некоторой части из полученных в результате декомпозиции подфункций Fi могут соответствовать известные объекты, которые называются элементами. Элемент, в свою очередь, может быть достаточно сложным. Существенным является то, что F-описание элемента не требует дальнейшей декомпозиции и, следовательно, он не имеет S-описания. Для оставшейся части Fi вновь необходима декомпозиция и т.д. до тех пор, пока все F-описания не будут соответствовать элементам.

Процесс декомпозиции F-описаний неоднозначен, причем множество допустимых решений достаточно велико. Выбор варианта декомпозиции обычно определяется качеством полученного решения, которое определяется так называемым параметрическим описанием или Р-описанием. Это описание формируется на основе выбора конечного множества критериев оценки качества проектируемого объекта и, в частности программы (такие критерии обсуждаются позднее).

Используя такую модель ОП процесс проектирования можно представить графом-деревом, изображенным на рис.2. Вершиной графа является двойка {F0, S0}, где 0 означает уровень представления, соответствующий вершине графа. На последующих уровнях вершины обозначены как двойки {FJi,SJi}, где Jозначает номер уровня, а i - порядковый номер компоненты. На основе Fjiформируется S-описание предыдущего уровня, т.е. Fji= SJ(FJ+1i), j=1,2,… ...,n, i=1,2, ...,mji, где iсоответствует количеству уровней, а mji – количеству компонент детализации Fji. На рисунке компонентыF1k , F3iqявляются элементами Такое определение процесса проектирования позволяет определить понятия, связанные с методологией проектирования, в частности такие, как нисходящее (сверху вниз) и восходящее (снизу вверх) проектирование.

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

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

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

 

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

 

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

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

 

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

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

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

 

Язык описания программ. В связи с тем, что термин “программирование” в дальнейшем означает программирование для ЭВМ, существенной оказывается еще одна проблема­ – выбор инструментальных средств или языка для описания программ. Здесь важен тот факт, что автором программ является человек (коллектив), а процессором - некоторая вычислительная система (условно - ЭВМ), которая реализует вычислительный процесс автоматически, без участия человека. Как будет показано ниже, ЭВМ воспринимает язык, содержащий только некоторые элементарные инструкции, которые крайне неудобны для человека. Очевидные противоречия разрешаются тем, что автор должен писать программы на удобном для него языке. Возникающее при этом несоответствие, как уже упоминалось, можно устранить автоматическим преобразованием одного вида текста программы в другой с помощью программы-транслятора.

 

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

 

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

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

Хорошим примером абстракции являются числа. Это абстракция того, что в реальном мире некоторые объекты можно объединять в группы. и пусть группа, например, состоит из пяти яблок. Последнее утверждение уже является абстракцией, так как не учитывает различия между яблоками, одно из которых может оказаться не созревшим, второе - гнилым и оба эти яблока красные, а остальные - желтые. Далее можно рассматривать несколько различных групп, таких как пять груш, апельсинов и т. п. Если отвлечься от отличий в группах и сосредоточиться на общем для всех групп свойстве, то можно прийти к абстрактному понятию числа 5. Точно также можно сформировать понятие других чисел, и, продолжая абстракцию, прийти к понятию натурального числа.

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

 

Впервые правила действий над числами были сформулированы Аль Хорезми задолго до нашей эры и потом назывались альхоризмами – словом, породившим современный термин “алгоритм”.

 

Таким образом, при абстрагировании можно выделить следующие стадии:

n абстракция: выбор существенных для рассмотрения свойств и назначение для абстракции уникального имени;

n спецификация: определение символьного представления абстрактных понятий:

n преобразования: определение конечного множества операций над символьным представлением для прогнозирования поведения реальных объектов в соответствии с абстракцией;

n аксиоматизация: строгая формулировка свойств объекта и правил преобразования.

 

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

 

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

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

Следующим этапом в разработке программы является абстракция данных, т.е. выбор форм представления абстрактной информации.

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

Собственно говоря, удобство и выразительная мощность языков высокого уровня в значительной степени связаны с наличием в языке удачных абстракций для описания данных и операций над ними. Так например, абстракция вида do s1,s2...sk while u определяет повторение последовательности действийs1,s2...sk, заданных между словами do (выполнить) и while (пока), до тех пор, пока условие uистинно, т.е. позволяет абстрагироваться от вида действий, вида условия и способа реализации этих действий в машине. Понятие абстракции в не меньшей степени распространяется на представление данных, так как машинное представление любых данных - это последовательность цифр, а программист, используя язык высокого уровня, оперирует такими элементами данных, как целое число, вещественное число, вектор, матрица и.т.п. Таким образом, инструментальные средства языков высокого уровня, точнее соответствующие им абстракции, позволяют:

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

n обеспечить независимость языков высокого уровня от типа вычислительной машины, поскольку абстракции реализуются в машинном представлении с помощью разработанного именно для этого типа машин транслятора;

n значительно уменьшить количество ошибок за счет проверки корректного применения абстракций (типы ошибок и возможность их обнаружения будут обсуждаться позднее).

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

Для изучения методологии структурного программирования в рамках курса используется язык Паскаль (версии Borland), поскольку этот язык является хорошим «макетом» для обсуждения концепций построения инструментальных средств современных языков программирования, ориентированных на структурную парадигму. При этом рассматриваются варианты реализации альтернативных концепций, используемых в других языках.