Парадигмы программирования логическое программирование

Статья Введение в основные принципы логического программирования [часть 1]

29675

Логи́ческое программи́рование — парадигма программирования, основанная на автоматическом доказательстве теорем, а также раздел дискретной математики, изучающий принципы логического вывода информации на основе заданных фактов и правил вывода.(c)Wikipedia

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

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

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

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

  • Imperative : в этой парадигме используются операторы для изменения состояния программы, что позволяет учитывать побочные эффекты.
  • Functional : эта парадигма рассматривает вычисления как оценку математических функций и не позволяет изменять состояния или изменяемые данные.
  • Declarative : это способ программирования, при котором вы пишете свои программы путем описывания, что именно вы хотите сделать, а не как вы хотите это сделать. Вы выражаете логику базовых вычислений без явного описания потока управления.
  • Object Oriented : в этой парадигме код группируется в программе таким образом, что каждый объект отвечает за себя. Объекты содержат данные и методы, которые определяют, каким именно образом происходят изменения.
  • Procedural : в этой парадигме код группируется по функциям, и каждая функция отвечает за определенную последовательность шагов.
  • Symbolic : в этой парадигме используется особый стиль синтаксиса и грамматики, с помощью которого программа может изменять свои собственные компоненты, рассматривая их как простые данные.
  • Logic : в этой парадигме вычисления рассматриваются как автоматическое обоснование базы данных знаний, состоящей из фактов и правил.
Читайте также:  Транспортная задача линейного программирования математика

Например, мы хотим вычислить сумму 23, 12 и 49:

Процедура будет выглядеть следующим образом:

23 + 12 + 49 => (2 + 1 + 4 + 1)4 => 84

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

Понимание составных элементов логического программирования

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

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

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

Факты — это просто утверждения, которые являются правдой о нашей программе и данных, с которыми она работает. Синтаксис довольно прост. Например, Дональд — сын Аллана, может быть фактом, тогда как, Кто сын Аллана? не может быть фактом.
Каждая логическая программа нуждается в фактах для работы, чтобы она могла достичь поставленной цели на их основе.
Правила — это та информация, которую мы узнали о том каким образом выражать различные факты и как их запрашивать. Это те ограничения, с которыми нам приходится работать, и они позволяют нам делать выводы о проблемной области.
Например, допустим, вы работаете над созданием шахматного движка. Вам нужно указать все правила о том, как каждая фигура может двигаться на шахматной доске. По сути, окончательный вывод действителен только в том случае, если все отношения/связи верны.

Решение проблем с помощью логического программирования

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

Кэти любит шоколад => Александр любит Кэти

Это можно прочитать как подтекст, который говорит: если Кэти любит шоколад, то Александр любит Кэти. Это также может быть истолковано как то, что Кэти любит шоколад подразумевает, что Александр любит Кэти.
Аналогично, давайте рассмотрим следующее правило:

Криминальные фильмы, английский язык => Martin Scorsese

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

Установка пакетов Python

Прежде чем мы начнем логическое программирование на Python, нам нужно установить пару пакетов. Пакет logpy — это пакет Python, который делает доступным логическое программирование на Python.
Мы также будем использовать sympy для решения некоторых проблем. Итак, давайте установим logpy и sympy с помощью pip :

$ pip3 install logpy $ pip3 install sympy

Согласование математических выражений

Мы постоянно сталкиваемся с математическими операциями. Логическое программирование — это очень эффективный способ сравнения выражений и обнаружения неизвестных значений. Давайте посмотрим, как это сделать.

Создайте новый файл Python и импортируйте следующие пакеты:

from logpy import run, var, fact import logpy.assoccomm as la
add = 'addition' mul = 'multiplication'
fact(la.commutative, mul) fact(la.commutative, add) fact(la.associative, mul) fact(la.associative, add)
expression_orig = 3 x (-2) + (1 + 2 x 3) x (-1)

Сгенерируем это выражение с замаскированными переменными.

expression1 = (1 + 2 x a) x b + 3 x c
expression2 = c x 3 + b x (2 x a + 1)
expression3 = (((2 x a) x b) + b) + 3 x

Если вы достаточно внимательны, вы заметите, что все три выражения представляют одно и то же основное выражение.
Наша цель — сопоставить эти выражения с исходным выражением для извлечения неизвестных значений:

expression_orig = (add, (mul, 3, -2), (mul, (add, 1, (mul, 2, 3)), -1)) expression1 = (add, (mul, (add, 1, (mul, 2, a)), b), (mul, 3, c)) expression2 = (add, (mul, c, 3), (mul, b, (add, (mul, 2, a), 1))) expression3 = (add, (add, (mul, (mul, 2, a), b), b), (mul, 3, c))

Сравните выражения с исходным выражением. Данный метод обычно используется в logpy . Этот метод принимает входные аргументы и выполняет выражение.
Первый аргумент — это число значений, второй аргумент — это переменная, а третий аргумент — это функция:

print(run(0, (a, b, c), la.eq_assoccomm(expression1, expression_orig))) print(run(0, (a, b, c), la.eq_assoccomm(expression2, expression_orig))) print(run(0, (a, b, c), la.eq_assoccomm(expression3, expression_orig)))

Полный код предоставлен в expression_matcher.py . Если вы запустите код, вы увидите следующий вывод в своем терминале:

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

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

Источник

Оцените статью