[I|process(P,T)].

advertisement
Сошников Дмитрий Валерьевич
к.ф.-м.н., доцент
dmitryso@microsoft.com
Факультет Прикладной математики и физики
Кафедра Вычислительной математики и программирования
Московский авиационный институт (государственный технический университет)
©2009 Сошников Д.В.

Решето Эратосфена
2
3
4
5
6
7
8
9
10
11
12
13
…
primes(N,L) :- integers(2,N,IL), filter(IL,L).
filter([],[]).
filter([I|L],[I|R]) :process(I,IS,T),
filter(T,R).
process(_,[],[]).
process(P,[I|T],R) :0 is I mod P, !,
process(P,T,R).
process(P,[I|T],[I|R]) :- process(P,T,R).
2
©2009 Сошников Д.В.
:- func primes(int) = list(int).
:- mode primes(in) = out is det.
primes(N) = filter(integers(2,N)).
:- func filter(list(int)) = list(int).
:- mode filter(in) = out is det.
filter([]) = [].
filter([I|L]) = [I|filter(process(I,L))].
:- func process(int,list(int)) = list(int).
:- mode process(in,in) = out is det.
process(_,[]) = [].
process(P,[I|T]) = R :0 is I mod P -->
R = process(P,T);
R = [I|process(P,T)].
3


©2009 Сошников Д.В.

Компиляторам с императивных языков
программирования надо было знать,
сколько памяти отводить под переменную
Тип = объем памяти + способ
интерпретации по умолчанию
(signed/unsigned)
В теории:
 Множество значений
 Множество операций и отношений
4
©2009 Сошников Д.В.


Встроенные типы
Конструируемые (получаемые из встроенных)
типы
 Перечислимый, диапазон
 Указатели
 Функциональные типы

Способы комбинирования типов:
 Массивы, записи, файлы

Абстрактные типы данных
 Функциональность типа данных, реализованная
как набор процедур/функций, удовлетворяющих
заданным аксиомам
5
©2009 Сошников Д.В.

Память выделяется (и освобождается)
динамически
 нет необходимости знать размер объекта заранее

Система типов (если есть) помогает
контролировать семантическую
правильность программы
 Может ли предикат принимать данный параметр?
 Может ли определенный параметр быть входным /
выходным

Более эффективная работа программы на
этапе выполнения
 Нет необходимости хранить информацию о типах
6
©2009 Сошников Д.В.
Языки со строгой типизацией
• Проверяется строгое соответствие типов
• Возможные исключения: наследование, полиморфизм
• Pascal, F#, C#, Java, SML, Mercury …
Языки с нестрогой типизацией
• Тип данных в основном нужен для определения объема памяти
• Совместимые по природе объекты (указатели на разные типы) совместимы
по присваиванию
• С, С++
Бестиповые языки (динамические)
• Переменные могут принимать значения различной природы
• LISP, Prolog, …
7
• На этапе компиляции
• Позволяет устранять большинство
логических ошибок до запуска
программы
• Более эффективная программа,
поскольку упоминание типов в
откомпилированной программе
отсутствует
• Требует более жесткой системы
типизации
• В традиционных языках обычно
требует избыточного описания
типов в программе
©2009 Сошников Д.В.
Статический
контроль типов
Динамический
контроль типов
• Происходит на этапе выполнения
• Меньше возможностей обнаружить
ошибку
• Может быть смоделирован на
бестиповых языках
• Более гибкий
8
©2009 Сошников Д.В.

Тип данных моделируется структурным
термом с соответствующим именем
avg_salary(
money(Total),
number(EmplNum),
money(Res)) :- Res is Total / EmplNum.

Несоответствие типа данных приводит к
невозможности унификации и неуспеху на
этапе выполнения
9
©2009 Сошников Д.В.

Системы типов в логических языках базируются на
строгих математических формализмах
 Многосортная логика предикатов
 Типизация Майкрофта-О’Кифа (базируется на типизации
Хиндли-Милнера для функциональных языков)

Используется автоматический вывод типов
 Программисту не нужно указывать тип значений
 Если тип значение указывается, это используется для
дополнительной проверки на этапе компиляции

Широко используется полиморфизм и
параметрическая типизация (generics)
 можно один раз определить операцию сразу для целого
класса типов
10
©2009 Сошников Д.В.
Множество типов или сортов T. Это
множество может состоять из элементарных
типов (например, {bool, int}) либо задаваться
при помощи конструкторов типов.
 Объявление типа t : t, где tT.
 Окружение G = { ti : ti }
 Выводимость объявления типа G├ t:t - в
окружении G можно заключить, что терм t
имеет тип t
 Множество правил вывода,

 посылками и заключениями являются
утверждения о выводимости объявления типа
11
©2009 Сошников Д.В.
Мономорфные типы
Тип
Синтаксис Mercury
Базовые типы: bool, int, char, string, …
:- type t == int
Функциональный тип T1→T2
:- type t == T1->T2
Декартово произведение T1T2
:- type t == T1 * T2
Прямая (помеченная) суммаT1+T2
:- type t --> op1(T1) ; op2( T2)
Полиморфные типы
:- type list(t) --> nil ; cons(t,list(t))
12


isTi : T→bool
makeTi : Ti→T

Примеры:
©2009 Сошников Д.В.

T1+T2 – множество значений Т1 Т2, при этом
можно различать между тем, какого типа
конкретное значение
T=T1+T2+…+Tn = { <i,xi> | i1..n, xi  Ti}

 bool = true | false
 int = 0 | s(int)
 list(τ) = ∅ | cons(τ, list(τ ))
13
©2009 Сошников Д.В.

Множество типов задается конструкторами
типов
 Прямая сумма
 Функциональный конструктор


На практике – предопределенные базовые
типы
Окружение
 Предикаты
 Структурные термы
 Переменные
14

©2009 Сошников Д.В.

Тип τ2 более общий, чем τ1 (τ1< τ2), если θ :
τ1 = θ τ2
Типы эквивалентны (τ1< τ2), если θ : θ τ1 =
θ τ2
15
16
©2009 Сошников Д.В.


©2009 Сошников Д.В.

Система типов называется корректной
относительно формальной
аксиоматической системы, если шаг
вывода в ФАС не нарушает корректности
типизации, т.е.
Г ├ t , t ├ s => Г ├ s
Это означает, что для правильной
типизации любого результата достаточно
статического контроля типов исходных
утверждений
17
©2009 Сошников Д.В.

Используем предикат = и функтор + для
сложения:
18
©2009 Сошников Д.В.

Варианты использования предиката:
Конкретизированы
Не конкретизированы
Семантика
Режим
X,Y
Z
Сложение
add(in,in,out)
X,Z
Y
Вычитание
add(in,out,in)
X,Y,Z
Построение всех
комбинаций
add(out,out,out)
Проверка верности
суммы
add(in,in,in)
X,Y,Z
19
©2009 Сошников Д.В.

Каждый режим доказательства приводит к своей
конфигурации дерева резолюции
 => есть специфика выполнение предиката в каждом из
режимов
 Оптимизация режимов доказательства

Некоторые режимы доказательства являются
частными случаями друг друга
 Основные режимы доказательства

Режим определяется тем, как изменяется
конкретизация параметров
 in – связанная переменная (остается связанной)
 out – свободная переменная конкретизируется
 Возможны другие варианты!
20
©2009 Сошников Д.В.

В языках ЛП возможно создание
неконкретизированных структур данных
 [_,_,_] – список из трех свободных элементов

Класс конкретизации (inst) показывает, как
конкретизированы составные части сложного
типа данных
 inst I = free | bound ({f(I1,I2, …),…})

Примеры:
 inst free_list = bound(nil | cons(free,free_list))
 inst ground – полностью конкретизированный терм
21



©2009 Сошников Д.В.

mode in = ground -> ground
mode out = free -> ground
mode fill_list = free_list -> ground
mode list_template = free -> free_list
22
©2009 Сошников Д.В.
Возможен
отказ?
Максимальное количество решений
0
1
более 1
выбор
нет
-
det
multi
cc_multi
да
failure
semidet
nondet
cc_nondet
23
©2009 Сошников Д.В.
:- pred fact(int,int).
:- mode fact(in,out) is cc_multi.
fact(1,1).
fact(N,R) :- N1 is N-1, fact(N1,R1), R is R1*N.
:- func fact(int) = int.
:- mode fact(in) = out is det.
fact(N) = R :- (N=<0 -> R=1 ; R is fact(N-1)*N).
24


©2009 Сошников Д.В.

P(x1,…,xn,y) – детерминированный предикат с
режимом P(in,…,in,out)
y = P(x1,…,xn)
Функции многих переменных можно
рассматривать как функцию высшего порядка
от одной переменной
 Для фикс. x функция f(x,y) определяет
одноместную функцию fx(y)
 f : int*int -> int
[некаррированная]
 f : int -> int -> int
[каррированная]
25
©2009 Сошников Д.В.

Аппликация – применение функции
высшего порядка к аргументу
 Понижение порядка на 1

Абстракция – рассмотрение выражения
как функции от некоторого аргумента
 Повышение порядка на 1
26
©2009 Сошников Д.В.
main -->
{solutions(lambda([X::out] is nondet,
specialty(X,programmer)),L)},
print(L),
nl.
27
©2009 Сошников Д.В.
Логические языки могут быть как
бестиповыми (Пролог), так и строго
типизированными (Mercury)
 Система типов в языках логического
программирования – формальная система
 Автоматический вывод типов и проверка
соответствия режимов и детерминизма
делают язык Mercury исключительно
надежным
 Логические языки по системе типизации (и не
только!) похожи на функциональные =>
логическо-функциональный подход!

28
Download