Сошников Дмитрий Валерьевич к.ф.-м.н., доцент [email protected] Факультет Прикладной математики и физики Кафедра Вычислительной математики и программирования Московский авиационный институт (государственный технический университет) ©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, где tT. Окружение 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 Декартово произведение T1T2 :- 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> | i1..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