Next:5.2.4
Упражнения
Up:5.2
Структурированные типы данных
Previous:5.2.2
Матрицы
Наличие у переменных типа массивов большого числа элементов затрудняет
рассмотрение массивов как совокупности независимых переменных. Кроме того,
индексы переменных массивов могут вычисляться. Поэтому при описании утверждений
о программах с массивами обычно используются дополнительные средства --
так называемые кванторы.
Пусть и -- два выражения некоторого скалярного типа, удовлетворяющие условию m<=n. Рассмотрим утверждение , где каждое некоторое утверждение. Оно истинно в любом состоянии, в котором истинно по меньшей мере одно из . Это утверждение можно выразить с помощью квантора существования (читается: "существует"): Множество значений, удовлетворяющих , называется областью значения квалифицированной переменной . На естественном языке приведенная запись читается следующим образом:
существует, по крайней мере, одно
:
такое, что
принадлежит отрезку m..Pred(n)
:
и для него справедливо
)
утверждение .
В подобной линейной форме
и
можно записывать и такие хорошо известные формы квантификации в математике, как сумма и произведение выражений , где и -- выражения целого типа.
Еще один важный квантор -- это квантор общности
(читается: "для всех"). Утверждение
истинно в некотором состоянии, если и только если
истинно в этом состоянии для всех
из области .
Другими словами, оно эквивалентно
(закон отрицания)
(закон де Моргана)
.
Еще один квантор -- это квантор счета
(читается: "количество различных"). Выражение
обозначает количество различных значений
из области ,
при которых
истинно. Это значит, что
.
До сих пор мы рассматривали области кванторов в виде ,
где
и
-- выражения некоторого скалярного типа. Утверждения с кванторами по прилегающим
друг к другу областям такого вида можно соединить следующим образом:
.
Можно обобщить понятие квантора, разрешив квалификацию по другим областям, в том числе и по бесконечным, например:
и ,
где -- идентификатор, а и -- утверждения, которые обычно (но вовсе не обязательно!) содержат . Смысл этих утверждений выражают следующие фразы: "существует значение из области (т.е. такое, для которого утверждение истинно), при котором E истинно"; "для всех значений из области утверждение E истинно".
Рассмотрим пример утверждения
о том, что K-- первое по величине натуральное число, являющееся нетривиальным делителем числа M. Это утверждение истинно, если ни одно из чисел 2,3,...,K-1 не является делителем числа M, а K делит M нацело. Таким образом, истинность утверждения в некотором состоянии выполнения программы зависит от значений переменных M и K, но не от значения ; на самом деле переменной с именем может даже не существовать при данном состоянии вычисления. Ясно, что смысл приведенного утверждения не изменится, если в нем все вхождения заменить на следующим образом:
.
Очевидно, что в рассмотренном утверждении у идентификатора иная роль, чем у идентификаторов M и K. Говорят, что M и K свободны в данном утверждении, а идентификатор связан в нем квантором . В приведенном на рис. 5.8 примере все связанные вхождения идентификаторов обозначены стрелками, ведущими от них к кванторам, которыми они связаны (не отмеченные стрелками вхождения являются свободными). Таким образом, каждое утверждение
вводит новый уровень обозначений. Внутри утверждения можно ссылаться на все имеющиеся вне его переменные, кроме переменной с именем . Эти переменные являются глобальными по отношению к утверждению. Часть является "описанием" нового локального идентификатора . Имя локального идентификатора не существенно и может быть изменено (всюду в утверждении) без изменения его смысла.
В качестве примера использования кванторов рассмотрим задачу сортировки 100 целых чисел -- в порядке неубывания их значений. Ее можно специфицировать следующим образом:
Программа: Сортировка
Вход:
где
Выход:
гдe,
Следующая программа является одним из ее возможных решений:
module СОРТИРОВКА;
(*Сортировка простым выбором*)
const N = 100;
type НОМЕР = integer; ВЕКТОР = array N
of integer;
var A : ВЕКТОР ; I,J,K : НОМЕР ; X : integer;
begin
for I := 1 to N do read(A[I])
end;
for I := 1 to N-1 do
(*{
}*)
K := I; X := A[I];
for J := I+1 to N do if A[J]
X then K :=J; X := A[J] end end;
(*{
}*)
A[K] := A[I]; A[I] := X
(*{}*)
end;
(*{}*)
for I := 1 to N do
write(A[I]) end
end СОРТИРОВКА.
Next:5.2.4
Упражнения
Up:5.2
Структурированные типы данных
Previous:5.2.2
Матрицы