SlideShare a Scribd company logo
1 of 81
Download to read offline
Making Logic Monad
@halcat0x15a
Recruit Marketing Partners Co., Ltd.
Table of Contents
• Background:What is Logic Programming?
• Backtracking and Unification
• Making Logic Monads
• Practical Applications
• Conclusions
今日話す内容です
Background
Logic Monad is based on Logic Programming.
First, we introduce Logic Programming with
Prolog.
Logicモナドは論理プログラミングに基づきます
まず、Prologによる論理プログラミングを紹介します
Logic Programming
Here is Prolog code:
my_append concatenates two lists.
これはPrologのコードです
my_appendは2つのリストを連結します
my_append([], L, L).
my_append([H|T1], L, [H|T2]) :-
my_append(T1, L, T2).
Logic Programming
my_append takes three parameters.
my_append has two clauses.
my_appendは3つのパラメータをとります
my_appendは2つの節をもちます
Logic Programming
• The first and second parameters are lists to
be concatenated.
• The third parameter is the concatenated
result.
1つめと2つめのパラメータは連結されるリストです
3つめのパラメータは連結した結果です
Logic Programming
Let's look at the first clause.
If the first list is empty, the concatenated result
equals the second list.
最初の節を見てみましょう
1つめのリストが空ならば連結した結果は2つめのリストです
my_append([], L, L).
Logic Programming
The head of the concatenated result equals the
head of the first list.
The tail of the concatenated result is the result
of concatenating the tail of the first list with the
second list.
連結した結果のheadは1つめのリストのheadと等しいです
tailは1つめのリストのtailと2つめのリストを連結した結果です
my_append([H|T1], L, [H|T2]) :-
my_append(T1, L, T2).
Logic Programming
The Prolog program run by giving a query.
The queries can include logical variables.
Prologのプログラムはクエリによって実行されます
クエリは論理変数を含めることができます
?- my_append([1],[2,3],X).
X = [1, 2, 3].
Logic Programming
my_append can calculate the difference between
two lists.
my_appendはリストの差分を計算できます
?- my_append(X,[2,3],[1,2,3]).
X = [1] ;
Logic Programming
my_append can calculate combinations of two
lists.
my_appendは2つのリストの組み合わせを計算できます
?- my_append(X,Y,[1,2,3]).
X = [], Y = [1, 2, 3] ;
X = [1], Y = [2, 3] ;
X = [1, 2], Y = [3] ;
X = [1, 2, 3], Y = [] ;
Logic Programming
my_append can perform various calculations
with just this definition.
my_appendはこの定義だけで様々な計算ができます
my_append([], L, L).
my_append([H|T1], L, [H|T2]) :-
my_append(T1, L, T2).
Goal
Today's goal is to realize my_append in Scala.
Next, we introduce Backtracking and
Unification, the components of Logic
Programming.
今日のゴールはmy_appendをScalaで実現することです
続いて論理プログラミングの構成要素について紹介します
Components
• Backtracking
• An algorithm for finding all solutions by
trying combinations of variables and
values.
• Unification
• An algorithm for calculating the
substitution that terms are identical.
バックトラッキングは解の探索アルゴリズムです
ユニフィケーションは置換を計算するアルゴリズムです
Backtracking
Backtracking computations also exists in Scala
Standard Library.
Here is a backtracking computation:
バックトラッキングはScalaの標準ライブラリにも存在します
for {
a <- List(1, 2, 3)
if a % 2 == 0
} yield a
Backtracking
Computations like filter can consider as
backtracking.
In other words, backtracking computations are
MonadPlus.
filterのような計算はバックトラッキングと見做せます
つまりバックトラッキングはMonadPlusです
Backtracking
MonadPlus satisfy the following interface:
MonadPlusはこのようなインターフェースを満たします
trait MonadPlus[M[_]] {
def empty[A]: M[A]
def plus[A](x: M[A], y: M[A]): M[A]
def pure[A](a: A): M[A]
def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B]
}
Backtracking
List is MonadPlus.
ListはMonadPlusです
trait ListMonadPlus extends MonadPlus[List] {
def empty[A] = Nil
def plus[A](x: List[A], y: List[A]) = x ::: y
def pure[A](a: A) = List(a)
def flatMap[A, B](ma: List[A])(f: A => List[B]) =
ma.flatMap(f)
}
Backtracking
You can write backtracking computations using
only MonadPlus primitives.
MonadPlusの関数だけでバックトラッキングを書けます
(List(1) ::: List(2) ::: List(3)).flatMap { a =>
if (a % 2 == 0) List(a) else Nil
}
Backtracking
The correspondence with primitives is as
follows:
プリミティブとの対応はこのようになります
(pure(1) plus pure(2) plus pure(3)).flatMap { a =>
if (a % 2 == 0) pure(a) else empty
}
Backtracking
• plus represents a disjunction.
• flatMap represents a conjunction.
• pure represents a success.
• empty represents a failure.
それぞれのプリミティブにはこのような対応があります
Unification
Unification is like an assignment.
Variables appear on the left and right sides.
ユニフィケーションは代入のようなものです
変数は左辺と右辺にあらわれます
A = 1
2 = B
Unification
Unification is like a comparison.
If a comparison fails, a program may backtrack.
ユニフィケーションは比較のようなものです
比較に失敗した場合プログラムはバックトラックします
1 = 1 % success
2 = 1 % failure
Unification
Data structures like List and Map unify
elements recursively.
ユニフィケーションは再帰的に行われます
[A] = [1]
{x: 1, y: B} = {x: C, y: 2}
Unification
Unification can be implemented by creating
logical variable relations.
ユニフィケーションは変数の関係を作ることで実装できます
Unification
The logical variable can be defined as follows:
論理変数はこのように定義できます
sealed trait LVar[A]
case class Bound[A](value: A) extends LVar[A]
case class Unbound[A](id: Int) extends LVar[A]
Unification
The result of the above unification is as follows:
上記のユニフィケーションの結果はこのようになります
Map(
0 -> Bound("foo"),
1 -> Bound("bar")
)
A = "foo"
"bar" = B
Unification
The result of the above unification is as follows:
上記のユニフィケーションの結果はこのようになります
C = D
Map(
0 -> Bound("foo"),
1 -> Bound("bar"),
2 -> Unbound(3),
3 -> Unbound(2)
)
Unification
The result of the above unification is as follows:
上記のユニフィケーションの結果はこのようになります
Map(
0 -> Bound("foo"),
1 -> Bound("bar"),
2 -> Unbound(3),
3 -> Bound("baz")
)
D = "baz"
Unification
The implementation of Unification requires to
express the state.
Backtracking computations and mutable data
types are incompatible.
Thus we introduce the State monad.
バックトラッキングと可変データ型は相性が悪いです
そこでStateモナドを導入します
Making Logic Monads
Logic is a combination of List monad and State
monad.
LogicはListモナドとStateモナドの組み合わせです
case class Logic[A](apply: State => List[(State, A)]) {
def flatMap[B](f: A => Logic[B]): Logic[B] =
Logic(s => apply(s).flatMap {
case (s, a) => f(a).apply(s)
})
def run: List[A] = apply(State.initial).map(_._2)
}
Making Logic Monads
State has a logical variable identifier and
relations.
Stateは論理変数のidと対応をもちます
case class State(id: Int, vars: IntMap[LVar[Any]])
object State {
val initial = State(0, IntMap.empty)
}
Making Logic Monads
Logic has the following primitives:
Logicにはこのようなプリミティブがあります
def success[A](a: A): Logic[A]
def failure[A]: Logic[A]
def choose[A](x: Logic[A], y: Logic[A]): Logic[A]
def get: Logic[State]
def put(state: State): Logic[Unit]
Making Logic Monads
Logic is MonadPlus.
LogicはMonadPlusです
trait LogicMonadPlus extends MonadPlus[Logic] {
def empty[A] = failure
def plus[A](x: Logic[A], y: Logic[A]) = choose(x, y)
def pure[A](a: A) = success(a)
def flatMap[A, B](ma: Logic[A])(f: A => Logic[B]) =
ma.flatMap(f)
}
Making Logic Monads
The following aliases are useful as logical
operators:
このような別名は論理演算子として便利です
def &&&[B](that: => Logic[B]): Logic[B] =
flatMap(_ => that)
def |||(that: => Logic[A]): Logic[A] =
choose(this, that)
Making Logic Monads
Logic is the State monad.
fresh creates a unique logical variable.
LogicはStateモナドです
freshは一意な論理変数を作ります
def fresh[A]: Logic[LVar[A]] =
for {
state <- get
_ <- put(state.copy(id = state.id + 1))
} yield Unbound(state.id)
Unification
Unify is a type class for unification.
The unification result type is Logic.
Unifyはユニフィケーションのための型クラスです
trait Unify[A] {
def unify(x: A, y: A): Logic[Unit]
}
Unification
The universal unification is as follows:
普遍的なユニフィケーションはこのようになります
implicit def UniversalUnify[A]: Unify[A] =
new Unify[A] {
def unify(x: A, y: A) =
if (x == y) success(()) else failure
}
Unification
Unification operators are provided as follows:
ユニフィケーションの演算子はこのように提供されます
implicit class UnifyOps[A](val self: A) {
def ===(that: A)(implicit A: Unify[A]) =
A.unify(self, that)
}
Unification
An example of a simple unification using Logic:
Logicを使ったシンプルなUnificationの例です
scala> val e0 = for {
| a <- LVar.fresh[String]
| _ <- a === "foo" ||| a === "bar"
| a <- a.get
| } yield a
scala> println(e0.run)
List(foo, bar)
Unification
get gets the value from a logical variable.
getは論理変数から値を取得します
def get: Logic[A] = this match {
case Bound(a) => Logic.success(a)
case Unbound(id) => for {
state <- Logic.get
a <- find(id, state.vars).fold(Logic.failure[A]) {
a => Logic.success(a.asInstanceOf[A])
}
} yield a
}
Unification
find follows relationships recursively.
findは関係を再帰的に辿ります
def find(key: Int, vars: Map[Int, LVar[Any]]) = {
@tailrec def loop(key: Int, path: Vector[Int]) =
vars.get(key) match {
case None => None
case Some(Bound(v)) => Some(v)
case Some(Unbound(k)) if path.contains(k) => None
case Some(Unbound(k)) => loop(k, path :+ k)
}
loop(key, Vector(key))
}
my_append in Scala
Now we are almost ready to implement
my_append.
But, Prolog’s pattern matching is difficult to
realize in Scala.
Thus we translate pattern matching into
primitive operations.
PrologのパターンマッチをScalaで実現するのは難しいです
そこで、パターンマッチを原始的な操作に翻訳します
my_append in Scala
Pattern matching is expressed as conjunctions
(,), disjunctions (;), and unification.
パターンマッチは論理積、論理和、ユニフィケーションとして
表現されます
my_append(X, Y, Z) :-
X = [], Y = Z;
X = [H|T1], Z = [H|T2], my_append(T1, Y, T2).
my_append in Scala
my_append in Scala is as follows:
Scalaのmy_appendはこのようになります
def append[A: Unify](x: LVar[LList[A]], y:
LVar[LList[A]], z: LVar[LList[A]]): Logic[Unit] =
for {
h <- LVar.fresh[A]
t1 <- LVar.fresh[LList[A]]
t2 <- LVar.fresh[LList[A]]
_ <- x === LNil[A] &&& y === z ||| x === LCons(h,
t1) &&& z === LCons(h, t2) &&& append(xt, y, zt)
} yield ()
my_append in Scala
LList is List using LVar.
LListはLVarを使ったListです
sealed trait LList[A]
case class LNil[A]() extends LList[A]
case class LCons[A](
head: LVar[A],
tail: LVar[LList[A]]
) extends LList[A]
my_append in Scala
The unification of LList unifies a head and a tail
respectively.
LListはheadとtailをそれぞれユニファイします
implicit def LListUnify[A](implicit A: Unify[A]) =
new Unify[LList[A]] {
def unify(x: LList[A], y: LList[A]) = (x, y) match {
case (LNil(), LNil()) => success(())
case (LCons(x, xs), LCons(y, ys)) =>
x === y &&& xs === ys
case _ => failure
}
}
my_append in Scala
LList can be converted to Scala's List.
LListはScalaのリストに変換することができます
def toList: Logic[List[A]] = this match {
case LNil() => success(Nil)
case LCons(h, t) => for {
h <- h.get
t <- t.get
t <- t.toList
} yield h :: t
}
my_append in Scala
my_append works as follows:
my_appendはこのように動作します
scala>val e1 = for {
| x <- LVar.fresh[LList[Int]]
| _ <- append(LList(1, 2), LList(3), x)
| x <- x.toList
|} yield x
scala>println(e1.run)
List(List(1, 2, 3))
my_append in Scala
my_append works as follows:
my_appendはこのように動作します
scala>val e2 = for {
| x <- LVar.fresh[LList[Int]]
| y <- LVar.fresh[LList[Int]]
| _ <- append(x, y, LList(1, 2, 3))
| x <- x.toList; y <- y.toList
|} yield (x, y)
scala>println(e2.run)
List((List(),List(1, 2, 3)), (List(1),List(2, 3)),
(List(1, 2),List(3)), (List(1, 2, 3),List()))
my_append in Scala
Congrats! It seems to be working properly.
正しく動いているようにみえます
Problems
• This implementation is not stack-safe.
• This implementation depends on specific
data structures like List.
問題として、この実装はスタックセーフではなく
Listのような特定のデータ構造に依存します
Problems
We introduce Freer monads to solve these
problems.
これらの問題を解決するためにFreerモナドを導入します
Freer Monads
Freer monads can represent arbitrary monads.
Modern implementations of Freer monads use
type-aligned sequences.
Freerモナドは任意のモナドを表現できます
モダンな実装にはType-aligned Sequenceが使われます
Type-aligned Sequence
Type-aligned Sequence is a sequence of
functions that represents a function.
Function composition is implemented by
concatenating sequences.
Type-aligned Sequenceは関数を表現する関数の列です
関数の合成は列の結合で実装されます
val f: A => C = TASeq(A => B, B => C)
val g: A => D = f ++ TASeq(C => D)
Type-aligned Sequence
Function application is performed in stack-safe
by applying from the head of the sequence.
関数の適用はスタックセーフに実行されます
val h = TASeq(A => B, B => C, C => D)
val D = h(A)
Freer Monads
Freer monad has two constructors:
Freerモナドは2つのコンストラクタをもちます
sealed trait Freer[F[_], A]
case class Pure[F[_], A](value: A)
extends Freer[F, A]
case class Impure[F[_], A, B](
effect: F[A],
arrs: Arrs[F, A, B]
) extends Freer[F, B]
Freer Monads
• Pure represents a computation without
side effects.
• Impure represents a computation with side
effects.
Pureは副作用のない計算を表します
Impureは副作用付きの計算を表します
Freer Monads
Arrs is Type-aligned Sequence specialized for
Freer.
ArrsはFreerに特殊化されたType-aligned Sequenceです
trait Arrs[F[_], A, B] {
def :+[C](f: B => Freer[F, C]): Arrs[F, A, C]
def ++[C](that: Arrs[F, B, C]): Arrs[F, A, C]
def apply(a: A): Freer[F, B]
}
Freer Monads
Freer Monads using Type-aligned Sequence
achieves fast monad composition.
TASeq使ったFreerは高速なモナドの合成を実現します
def flatMap[B](f: A => Freer[F, B]): Freer[F, B] =
this match {
case Pure(a) => f(a)
case Impure(fa, k) => Impure(fa, k :+ f)
}
Freer Monads
Side effects mean the following computations:
副作用とはこのような計算を意味します
def failure[A]: Logic[A]
def choose[A](x: Logic[A], y: Logic[A]): Logic[A]
def get: Logic[State]
def put(state: State): Logic[Unit]
Algebraic Effects
Logic effects can be defined as data types.
Logicの副作用をデータ型として定義できます
sealed trait LogicEffect[+A]
case object Failure extends LogicEffect[Nothing]
case object Choose extends LogicEffect[Boolean]
case object Get extends LogicEffect[State]
case class Put(state: State) extends LogicEffect[Unit]
Algebraic Effects
Logic is defined as an alias for Freer.
LogicはFreerの別名として定義されます
type Logic[A] = Freer[LogicEffect, A]
def success[A](a: A): Logic[A] = Pure(a)
def failure[A]: Logic[A] = Impure(Failure, Arrs.id)
Algebraic Effects
choose switches continuations with Boolean.
chooseはBooleanによって継続を切り替えます
def choose[A](x: Logic[A], y: Logic[A]): Logic[A] =
Impure(Choose, Arrs.id).flatMap(if (_) x else y)
def get: Logic[State] = Impure(Get, Arrs.id)
def put(state: State): Logic[Unit] =
Impure(Put(state), Arrs.id)
Effect Handlers
Logic can be handled as List.
LogicはListとして処理できます
def runList[A](logic: Logic[A], s: State): List[A] =
logic match {
case Pure(a) => List(a)
case Impure(Failure, _) => Nil
case Impure(Choose, k) =>
runList(s)(k(true)) ::: runList(s)(k(false))
case Impure(Get, k) => runList(s)(k(s))
case Impure(Put(s), k) => runList(s)(k(()))
}
Effect Handlers
We can define various other effect handlers.
• Handle in constant space asVector
• Handle infinite solutions as Stream
• Customize solution search algorithm
他にも様々なエフェクトハンドラを定義することができます
Practical Applications
Let's consider a practical application with Logic.
It is good to have loops and conditionals.
ここでLogicによる実践的なアプリケーションを考えます
ループや条件分岐を含むものが良いです
Practical Applications
So it's Fizz Buzz.
そこでFizz Buzzです
def fizzbuzz(n: Int): Logic[String] =
(n % 15 === 0).map(_ => "FizzBuzz") |||
(n % 3 === 0).map(_ => "Fizz") |||
(n % 5 === 0).map(_ => "Buzz") |||
success(n.toString)
Practical Applications
But there is a problem with this Fizz Buzz:
The problem is that backtracking gives you all
solutions.
しかしこのFizzBuzzには問題があって、
バックトラッキングによって全ての解が得られてしまいます
scala> println(run(fizzbuzz(15)))
List(FizzBuzz, Fizz, Buzz, 15)
Practical Applications
Prolog solves the problem by using the cut
operator.
The cut operator can perform pruning and
logical negation.
Prologはcut演算子によりこの問題を解決しています
cutは枝刈りや論理的な否定ができます
Practical Applications
There is one primitive to implement the
functionality of the cut operator:
cutの機能を実装するためのプリミティブがあります
def split[A](logic: Logic[A])
: Logic[Option[(A, Logic[A])]]
Practical Applications
split is an operation that splits Logic into head
and tail.
If it can be split, it returns Some, otherwise it
returns None.
splitはLogicをheadとtailに分割します
分割できればSomeで返し、そうでないならNoneを返します
Practical Applications
Freer monads are good at partially handling
side effects.
The next slide shows the implementation.
Freerモナドは副作用を部分的に処理することが得意です
次のスライドに実装を示します
Practical Applications
splitの実装です
def split[A](logic: Logic[A]) = {
def go(logic: Logic[A], state: State) =
logic match {
case Pure(a) => success(Some((a, failure)))
case Impure(Failure, _) => success(None)
case Impure(Choose, k) =>
go(k(true), state).map(_.map {
case (a, t) => (a, t ||| k(false))
})
case Impure(Get, k) => go(k(state), state)
case Impure(Put(state), k) => go(k(()), state)
}
get.flatMap(go(logic, _))
}
Practical Applications
We can define a conditional with split:
splitで条件分岐を定義できます
def ifte[A, B](logic: Logic[A])(th: A => Logic[B])(el:
Logic[B]): Logic[B] =
split(logic).flatMap {
case None => el
case Some((a, t)) => th(a) ||| t.flatMap(th)
}
Practical Applications
Make useful operators.
便利な演算子を作って
def orElse(that: => Logic[A]): Logic[A] =
ifte(this)(success)(that)
Practical Applications
Rewrite Fizz Buzz.
それで書き換えて
def fizzbuzz(n: Int): Logic[String] =
(n % 15 === 0).map(_ => "FizzBuzz") orElse
(n % 3 === 0).map(_ => "Fizz") orElse
(n % 5 === 0).map(_ => "Buzz") orElse
success(n.toString)
Practical Applications
Perfect!
完璧です
scala>val e3 = for {
| n <- (1 to 15).foldMap(success)
| s <- fizzbuzz(n)
|} yield s
scala> println(run(e3))
List(1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz,
11, Fizz, 13, 14, FizzBuzz)
Conclusions
• Logic Programming consists of Backtracking
and Unification.
• Backtracking computations is MonadPlus.
• Freer monads and Type-aligned Sequence
provide stack safety.
• The representation of effects as data types
can give different interpretations.
結論です
References
• https://github.com/halcat0x15a/logical
• http://okmij.org/ftp/Computation/LogicT.pdf
• http://okmij.org/ftp/Haskell/extensible/
more.pdf
参考文献です
Thank you

More Related Content

What's hot

An introduction to Jupyter notebooks and the Noteable service
An introduction to Jupyter notebooks and the Noteable serviceAn introduction to Jupyter notebooks and the Noteable service
An introduction to Jupyter notebooks and the Noteable serviceJisc
 
Présentation de la Plateforme Nuxeo
Présentation de la Plateforme NuxeoPrésentation de la Plateforme Nuxeo
Présentation de la Plateforme NuxeoNuxeo
 
Programming in Python
Programming in Python Programming in Python
Programming in Python Tiji Thomas
 
Beginners PHP Tutorial
Beginners PHP TutorialBeginners PHP Tutorial
Beginners PHP Tutorialalexjones89
 
Jupyter, A Platform for Data Science at Scale
Jupyter, A Platform for Data Science at ScaleJupyter, A Platform for Data Science at Scale
Jupyter, A Platform for Data Science at ScaleMatthias Bussonnier
 
Python Visual Studio | Edureka
Python Visual Studio | EdurekaPython Visual Studio | Edureka
Python Visual Studio | EdurekaEdureka!
 
Immutable vs mutable data types in python
Immutable vs mutable data types in pythonImmutable vs mutable data types in python
Immutable vs mutable data types in pythonLearnbay Datascience
 
Learn Python The Hard Way Presentation
Learn Python The Hard Way PresentationLearn Python The Hard Way Presentation
Learn Python The Hard Way PresentationAmira ElSharkawy
 
Rodando uma API Com Django Rest Framework no Google Cloud
Rodando uma API Com Django Rest Framework  no Google CloudRodando uma API Com Django Rest Framework  no Google Cloud
Rodando uma API Com Django Rest Framework no Google CloudAlvaro Viebrantz
 
PhNOG Report APRICOT 2023
PhNOG Report APRICOT 2023PhNOG Report APRICOT 2023
PhNOG Report APRICOT 2023APNIC
 
Formation jpa-hibernate-spring-data
Formation jpa-hibernate-spring-dataFormation jpa-hibernate-spring-data
Formation jpa-hibernate-spring-dataLhouceine OUHAMZA
 
Introduction To Dotnet
Introduction To DotnetIntroduction To Dotnet
Introduction To DotnetSAMIR BHOGAYTA
 
Intro to Python Programming Language
Intro to Python Programming LanguageIntro to Python Programming Language
Intro to Python Programming LanguageDipankar Achinta
 
Chatbot with RASA | Valuebound
Chatbot with RASA | ValueboundChatbot with RASA | Valuebound
Chatbot with RASA | Valueboundvaluebound
 
Introduction to python for Beginners
Introduction to python for Beginners Introduction to python for Beginners
Introduction to python for Beginners Sujith Kumar
 

What's hot (20)

An introduction to Jupyter notebooks and the Noteable service
An introduction to Jupyter notebooks and the Noteable serviceAn introduction to Jupyter notebooks and the Noteable service
An introduction to Jupyter notebooks and the Noteable service
 
Présentation de la Plateforme Nuxeo
Présentation de la Plateforme NuxeoPrésentation de la Plateforme Nuxeo
Présentation de la Plateforme Nuxeo
 
Programming in Python
Programming in Python Programming in Python
Programming in Python
 
Python
PythonPython
Python
 
Python : Data Types
Python : Data TypesPython : Data Types
Python : Data Types
 
Beginners PHP Tutorial
Beginners PHP TutorialBeginners PHP Tutorial
Beginners PHP Tutorial
 
Basics of python
Basics of pythonBasics of python
Basics of python
 
Jupyter, A Platform for Data Science at Scale
Jupyter, A Platform for Data Science at ScaleJupyter, A Platform for Data Science at Scale
Jupyter, A Platform for Data Science at Scale
 
Python Visual Studio | Edureka
Python Visual Studio | EdurekaPython Visual Studio | Edureka
Python Visual Studio | Edureka
 
Immutable vs mutable data types in python
Immutable vs mutable data types in pythonImmutable vs mutable data types in python
Immutable vs mutable data types in python
 
Presentation Spring
Presentation SpringPresentation Spring
Presentation Spring
 
Learn Python The Hard Way Presentation
Learn Python The Hard Way PresentationLearn Python The Hard Way Presentation
Learn Python The Hard Way Presentation
 
Python basic
Python basicPython basic
Python basic
 
Rodando uma API Com Django Rest Framework no Google Cloud
Rodando uma API Com Django Rest Framework  no Google CloudRodando uma API Com Django Rest Framework  no Google Cloud
Rodando uma API Com Django Rest Framework no Google Cloud
 
PhNOG Report APRICOT 2023
PhNOG Report APRICOT 2023PhNOG Report APRICOT 2023
PhNOG Report APRICOT 2023
 
Formation jpa-hibernate-spring-data
Formation jpa-hibernate-spring-dataFormation jpa-hibernate-spring-data
Formation jpa-hibernate-spring-data
 
Introduction To Dotnet
Introduction To DotnetIntroduction To Dotnet
Introduction To Dotnet
 
Intro to Python Programming Language
Intro to Python Programming LanguageIntro to Python Programming Language
Intro to Python Programming Language
 
Chatbot with RASA | Valuebound
Chatbot with RASA | ValueboundChatbot with RASA | Valuebound
Chatbot with RASA | Valuebound
 
Introduction to python for Beginners
Introduction to python for Beginners Introduction to python for Beginners
Introduction to python for Beginners
 

Similar to Making Logic Monad

A brief introduction to apply functions
A brief introduction to apply functionsA brief introduction to apply functions
A brief introduction to apply functionsNIKET CHAURASIA
 
Functional Programming by Examples using Haskell
Functional Programming by Examples using HaskellFunctional Programming by Examples using Haskell
Functional Programming by Examples using Haskellgoncharenko
 
Loops and functions in r
Loops and functions in rLoops and functions in r
Loops and functions in rmanikanta361
 
Morel, a data-parallel programming language
Morel, a data-parallel programming languageMorel, a data-parallel programming language
Morel, a data-parallel programming languageJulian Hyde
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Languagevsssuresh
 
Morel, a Functional Query Language
Morel, a Functional Query LanguageMorel, a Functional Query Language
Morel, a Functional Query LanguageJulian Hyde
 
Scala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsKirill Kozlov
 
How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1Taisuke Oe
 
Real Time Big Data Management
Real Time Big Data ManagementReal Time Big Data Management
Real Time Big Data ManagementAlbert Bifet
 
Introduction to Matlab.pdf
Introduction to Matlab.pdfIntroduction to Matlab.pdf
Introduction to Matlab.pdfssuser43b38e
 
The what over the how (another way on android development with kotlin)
The what over the how (another way on android development with kotlin)The what over the how (another way on android development with kotlin)
The what over the how (another way on android development with kotlin)Jose Manuel Pereira Garcia
 
Introduction to matlab
Introduction to matlabIntroduction to matlab
Introduction to matlabBilawalBaloch1
 
Fuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional ProgrammingFuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional ProgrammingShine Xavier
 
List-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic LanguagesList-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic LanguagesWim Vanderbauwhede
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Sheik Uduman Ali
 

Similar to Making Logic Monad (20)

Practical cats
Practical catsPractical cats
Practical cats
 
A brief introduction to apply functions
A brief introduction to apply functionsA brief introduction to apply functions
A brief introduction to apply functions
 
Functional Programming by Examples using Haskell
Functional Programming by Examples using HaskellFunctional Programming by Examples using Haskell
Functional Programming by Examples using Haskell
 
Loops and functions in r
Loops and functions in rLoops and functions in r
Loops and functions in r
 
Morel, a data-parallel programming language
Morel, a data-parallel programming languageMorel, a data-parallel programming language
Morel, a data-parallel programming language
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
 
Morel, a Functional Query Language
Morel, a Functional Query LanguageMorel, a Functional Query Language
Morel, a Functional Query Language
 
Programming in R
Programming in RProgramming in R
Programming in R
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
 
Frp2016 3
Frp2016 3Frp2016 3
Frp2016 3
 
Scala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. Monads
 
R Language Introduction
R Language IntroductionR Language Introduction
R Language Introduction
 
How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
 
Real Time Big Data Management
Real Time Big Data ManagementReal Time Big Data Management
Real Time Big Data Management
 
Introduction to Matlab.pdf
Introduction to Matlab.pdfIntroduction to Matlab.pdf
Introduction to Matlab.pdf
 
The what over the how (another way on android development with kotlin)
The what over the how (another way on android development with kotlin)The what over the how (another way on android development with kotlin)
The what over the how (another way on android development with kotlin)
 
Introduction to matlab
Introduction to matlabIntroduction to matlab
Introduction to matlab
 
Fuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional ProgrammingFuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional Programming
 
List-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic LanguagesList-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic Languages
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0
 

Recently uploaded

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 

Recently uploaded (20)

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

Making Logic Monad

  • 1. Making Logic Monad @halcat0x15a Recruit Marketing Partners Co., Ltd.
  • 2. Table of Contents • Background:What is Logic Programming? • Backtracking and Unification • Making Logic Monads • Practical Applications • Conclusions 今日話す内容です
  • 3. Background Logic Monad is based on Logic Programming. First, we introduce Logic Programming with Prolog. Logicモナドは論理プログラミングに基づきます まず、Prologによる論理プログラミングを紹介します
  • 4. Logic Programming Here is Prolog code: my_append concatenates two lists. これはPrologのコードです my_appendは2つのリストを連結します my_append([], L, L). my_append([H|T1], L, [H|T2]) :- my_append(T1, L, T2).
  • 5. Logic Programming my_append takes three parameters. my_append has two clauses. my_appendは3つのパラメータをとります my_appendは2つの節をもちます
  • 6. Logic Programming • The first and second parameters are lists to be concatenated. • The third parameter is the concatenated result. 1つめと2つめのパラメータは連結されるリストです 3つめのパラメータは連結した結果です
  • 7. Logic Programming Let's look at the first clause. If the first list is empty, the concatenated result equals the second list. 最初の節を見てみましょう 1つめのリストが空ならば連結した結果は2つめのリストです my_append([], L, L).
  • 8. Logic Programming The head of the concatenated result equals the head of the first list. The tail of the concatenated result is the result of concatenating the tail of the first list with the second list. 連結した結果のheadは1つめのリストのheadと等しいです tailは1つめのリストのtailと2つめのリストを連結した結果です my_append([H|T1], L, [H|T2]) :- my_append(T1, L, T2).
  • 9. Logic Programming The Prolog program run by giving a query. The queries can include logical variables. Prologのプログラムはクエリによって実行されます クエリは論理変数を含めることができます ?- my_append([1],[2,3],X). X = [1, 2, 3].
  • 10. Logic Programming my_append can calculate the difference between two lists. my_appendはリストの差分を計算できます ?- my_append(X,[2,3],[1,2,3]). X = [1] ;
  • 11. Logic Programming my_append can calculate combinations of two lists. my_appendは2つのリストの組み合わせを計算できます ?- my_append(X,Y,[1,2,3]). X = [], Y = [1, 2, 3] ; X = [1], Y = [2, 3] ; X = [1, 2], Y = [3] ; X = [1, 2, 3], Y = [] ;
  • 12. Logic Programming my_append can perform various calculations with just this definition. my_appendはこの定義だけで様々な計算ができます my_append([], L, L). my_append([H|T1], L, [H|T2]) :- my_append(T1, L, T2).
  • 13. Goal Today's goal is to realize my_append in Scala. Next, we introduce Backtracking and Unification, the components of Logic Programming. 今日のゴールはmy_appendをScalaで実現することです 続いて論理プログラミングの構成要素について紹介します
  • 14. Components • Backtracking • An algorithm for finding all solutions by trying combinations of variables and values. • Unification • An algorithm for calculating the substitution that terms are identical. バックトラッキングは解の探索アルゴリズムです ユニフィケーションは置換を計算するアルゴリズムです
  • 15. Backtracking Backtracking computations also exists in Scala Standard Library. Here is a backtracking computation: バックトラッキングはScalaの標準ライブラリにも存在します for { a <- List(1, 2, 3) if a % 2 == 0 } yield a
  • 16. Backtracking Computations like filter can consider as backtracking. In other words, backtracking computations are MonadPlus. filterのような計算はバックトラッキングと見做せます つまりバックトラッキングはMonadPlusです
  • 17. Backtracking MonadPlus satisfy the following interface: MonadPlusはこのようなインターフェースを満たします trait MonadPlus[M[_]] { def empty[A]: M[A] def plus[A](x: M[A], y: M[A]): M[A] def pure[A](a: A): M[A] def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B] }
  • 18. Backtracking List is MonadPlus. ListはMonadPlusです trait ListMonadPlus extends MonadPlus[List] { def empty[A] = Nil def plus[A](x: List[A], y: List[A]) = x ::: y def pure[A](a: A) = List(a) def flatMap[A, B](ma: List[A])(f: A => List[B]) = ma.flatMap(f) }
  • 19. Backtracking You can write backtracking computations using only MonadPlus primitives. MonadPlusの関数だけでバックトラッキングを書けます (List(1) ::: List(2) ::: List(3)).flatMap { a => if (a % 2 == 0) List(a) else Nil }
  • 20. Backtracking The correspondence with primitives is as follows: プリミティブとの対応はこのようになります (pure(1) plus pure(2) plus pure(3)).flatMap { a => if (a % 2 == 0) pure(a) else empty }
  • 21. Backtracking • plus represents a disjunction. • flatMap represents a conjunction. • pure represents a success. • empty represents a failure. それぞれのプリミティブにはこのような対応があります
  • 22. Unification Unification is like an assignment. Variables appear on the left and right sides. ユニフィケーションは代入のようなものです 変数は左辺と右辺にあらわれます A = 1 2 = B
  • 23. Unification Unification is like a comparison. If a comparison fails, a program may backtrack. ユニフィケーションは比較のようなものです 比較に失敗した場合プログラムはバックトラックします 1 = 1 % success 2 = 1 % failure
  • 24. Unification Data structures like List and Map unify elements recursively. ユニフィケーションは再帰的に行われます [A] = [1] {x: 1, y: B} = {x: C, y: 2}
  • 25. Unification Unification can be implemented by creating logical variable relations. ユニフィケーションは変数の関係を作ることで実装できます
  • 26. Unification The logical variable can be defined as follows: 論理変数はこのように定義できます sealed trait LVar[A] case class Bound[A](value: A) extends LVar[A] case class Unbound[A](id: Int) extends LVar[A]
  • 27. Unification The result of the above unification is as follows: 上記のユニフィケーションの結果はこのようになります Map( 0 -> Bound("foo"), 1 -> Bound("bar") ) A = "foo" "bar" = B
  • 28. Unification The result of the above unification is as follows: 上記のユニフィケーションの結果はこのようになります C = D Map( 0 -> Bound("foo"), 1 -> Bound("bar"), 2 -> Unbound(3), 3 -> Unbound(2) )
  • 29. Unification The result of the above unification is as follows: 上記のユニフィケーションの結果はこのようになります Map( 0 -> Bound("foo"), 1 -> Bound("bar"), 2 -> Unbound(3), 3 -> Bound("baz") ) D = "baz"
  • 30. Unification The implementation of Unification requires to express the state. Backtracking computations and mutable data types are incompatible. Thus we introduce the State monad. バックトラッキングと可変データ型は相性が悪いです そこでStateモナドを導入します
  • 31. Making Logic Monads Logic is a combination of List monad and State monad. LogicはListモナドとStateモナドの組み合わせです case class Logic[A](apply: State => List[(State, A)]) { def flatMap[B](f: A => Logic[B]): Logic[B] = Logic(s => apply(s).flatMap { case (s, a) => f(a).apply(s) }) def run: List[A] = apply(State.initial).map(_._2) }
  • 32. Making Logic Monads State has a logical variable identifier and relations. Stateは論理変数のidと対応をもちます case class State(id: Int, vars: IntMap[LVar[Any]]) object State { val initial = State(0, IntMap.empty) }
  • 33. Making Logic Monads Logic has the following primitives: Logicにはこのようなプリミティブがあります def success[A](a: A): Logic[A] def failure[A]: Logic[A] def choose[A](x: Logic[A], y: Logic[A]): Logic[A] def get: Logic[State] def put(state: State): Logic[Unit]
  • 34. Making Logic Monads Logic is MonadPlus. LogicはMonadPlusです trait LogicMonadPlus extends MonadPlus[Logic] { def empty[A] = failure def plus[A](x: Logic[A], y: Logic[A]) = choose(x, y) def pure[A](a: A) = success(a) def flatMap[A, B](ma: Logic[A])(f: A => Logic[B]) = ma.flatMap(f) }
  • 35. Making Logic Monads The following aliases are useful as logical operators: このような別名は論理演算子として便利です def &&&[B](that: => Logic[B]): Logic[B] = flatMap(_ => that) def |||(that: => Logic[A]): Logic[A] = choose(this, that)
  • 36. Making Logic Monads Logic is the State monad. fresh creates a unique logical variable. LogicはStateモナドです freshは一意な論理変数を作ります def fresh[A]: Logic[LVar[A]] = for { state <- get _ <- put(state.copy(id = state.id + 1)) } yield Unbound(state.id)
  • 37. Unification Unify is a type class for unification. The unification result type is Logic. Unifyはユニフィケーションのための型クラスです trait Unify[A] { def unify(x: A, y: A): Logic[Unit] }
  • 38. Unification The universal unification is as follows: 普遍的なユニフィケーションはこのようになります implicit def UniversalUnify[A]: Unify[A] = new Unify[A] { def unify(x: A, y: A) = if (x == y) success(()) else failure }
  • 39. Unification Unification operators are provided as follows: ユニフィケーションの演算子はこのように提供されます implicit class UnifyOps[A](val self: A) { def ===(that: A)(implicit A: Unify[A]) = A.unify(self, that) }
  • 40. Unification An example of a simple unification using Logic: Logicを使ったシンプルなUnificationの例です scala> val e0 = for { | a <- LVar.fresh[String] | _ <- a === "foo" ||| a === "bar" | a <- a.get | } yield a scala> println(e0.run) List(foo, bar)
  • 41. Unification get gets the value from a logical variable. getは論理変数から値を取得します def get: Logic[A] = this match { case Bound(a) => Logic.success(a) case Unbound(id) => for { state <- Logic.get a <- find(id, state.vars).fold(Logic.failure[A]) { a => Logic.success(a.asInstanceOf[A]) } } yield a }
  • 42. Unification find follows relationships recursively. findは関係を再帰的に辿ります def find(key: Int, vars: Map[Int, LVar[Any]]) = { @tailrec def loop(key: Int, path: Vector[Int]) = vars.get(key) match { case None => None case Some(Bound(v)) => Some(v) case Some(Unbound(k)) if path.contains(k) => None case Some(Unbound(k)) => loop(k, path :+ k) } loop(key, Vector(key)) }
  • 43. my_append in Scala Now we are almost ready to implement my_append. But, Prolog’s pattern matching is difficult to realize in Scala. Thus we translate pattern matching into primitive operations. PrologのパターンマッチをScalaで実現するのは難しいです そこで、パターンマッチを原始的な操作に翻訳します
  • 44. my_append in Scala Pattern matching is expressed as conjunctions (,), disjunctions (;), and unification. パターンマッチは論理積、論理和、ユニフィケーションとして 表現されます my_append(X, Y, Z) :- X = [], Y = Z; X = [H|T1], Z = [H|T2], my_append(T1, Y, T2).
  • 45. my_append in Scala my_append in Scala is as follows: Scalaのmy_appendはこのようになります def append[A: Unify](x: LVar[LList[A]], y: LVar[LList[A]], z: LVar[LList[A]]): Logic[Unit] = for { h <- LVar.fresh[A] t1 <- LVar.fresh[LList[A]] t2 <- LVar.fresh[LList[A]] _ <- x === LNil[A] &&& y === z ||| x === LCons(h, t1) &&& z === LCons(h, t2) &&& append(xt, y, zt) } yield ()
  • 46. my_append in Scala LList is List using LVar. LListはLVarを使ったListです sealed trait LList[A] case class LNil[A]() extends LList[A] case class LCons[A]( head: LVar[A], tail: LVar[LList[A]] ) extends LList[A]
  • 47. my_append in Scala The unification of LList unifies a head and a tail respectively. LListはheadとtailをそれぞれユニファイします implicit def LListUnify[A](implicit A: Unify[A]) = new Unify[LList[A]] { def unify(x: LList[A], y: LList[A]) = (x, y) match { case (LNil(), LNil()) => success(()) case (LCons(x, xs), LCons(y, ys)) => x === y &&& xs === ys case _ => failure } }
  • 48. my_append in Scala LList can be converted to Scala's List. LListはScalaのリストに変換することができます def toList: Logic[List[A]] = this match { case LNil() => success(Nil) case LCons(h, t) => for { h <- h.get t <- t.get t <- t.toList } yield h :: t }
  • 49. my_append in Scala my_append works as follows: my_appendはこのように動作します scala>val e1 = for { | x <- LVar.fresh[LList[Int]] | _ <- append(LList(1, 2), LList(3), x) | x <- x.toList |} yield x scala>println(e1.run) List(List(1, 2, 3))
  • 50. my_append in Scala my_append works as follows: my_appendはこのように動作します scala>val e2 = for { | x <- LVar.fresh[LList[Int]] | y <- LVar.fresh[LList[Int]] | _ <- append(x, y, LList(1, 2, 3)) | x <- x.toList; y <- y.toList |} yield (x, y) scala>println(e2.run) List((List(),List(1, 2, 3)), (List(1),List(2, 3)), (List(1, 2),List(3)), (List(1, 2, 3),List()))
  • 51. my_append in Scala Congrats! It seems to be working properly. 正しく動いているようにみえます
  • 52. Problems • This implementation is not stack-safe. • This implementation depends on specific data structures like List. 問題として、この実装はスタックセーフではなく Listのような特定のデータ構造に依存します
  • 53. Problems We introduce Freer monads to solve these problems. これらの問題を解決するためにFreerモナドを導入します
  • 54. Freer Monads Freer monads can represent arbitrary monads. Modern implementations of Freer monads use type-aligned sequences. Freerモナドは任意のモナドを表現できます モダンな実装にはType-aligned Sequenceが使われます
  • 55. Type-aligned Sequence Type-aligned Sequence is a sequence of functions that represents a function. Function composition is implemented by concatenating sequences. Type-aligned Sequenceは関数を表現する関数の列です 関数の合成は列の結合で実装されます val f: A => C = TASeq(A => B, B => C) val g: A => D = f ++ TASeq(C => D)
  • 56. Type-aligned Sequence Function application is performed in stack-safe by applying from the head of the sequence. 関数の適用はスタックセーフに実行されます val h = TASeq(A => B, B => C, C => D) val D = h(A)
  • 57. Freer Monads Freer monad has two constructors: Freerモナドは2つのコンストラクタをもちます sealed trait Freer[F[_], A] case class Pure[F[_], A](value: A) extends Freer[F, A] case class Impure[F[_], A, B]( effect: F[A], arrs: Arrs[F, A, B] ) extends Freer[F, B]
  • 58. Freer Monads • Pure represents a computation without side effects. • Impure represents a computation with side effects. Pureは副作用のない計算を表します Impureは副作用付きの計算を表します
  • 59. Freer Monads Arrs is Type-aligned Sequence specialized for Freer. ArrsはFreerに特殊化されたType-aligned Sequenceです trait Arrs[F[_], A, B] { def :+[C](f: B => Freer[F, C]): Arrs[F, A, C] def ++[C](that: Arrs[F, B, C]): Arrs[F, A, C] def apply(a: A): Freer[F, B] }
  • 60. Freer Monads Freer Monads using Type-aligned Sequence achieves fast monad composition. TASeq使ったFreerは高速なモナドの合成を実現します def flatMap[B](f: A => Freer[F, B]): Freer[F, B] = this match { case Pure(a) => f(a) case Impure(fa, k) => Impure(fa, k :+ f) }
  • 61. Freer Monads Side effects mean the following computations: 副作用とはこのような計算を意味します def failure[A]: Logic[A] def choose[A](x: Logic[A], y: Logic[A]): Logic[A] def get: Logic[State] def put(state: State): Logic[Unit]
  • 62. Algebraic Effects Logic effects can be defined as data types. Logicの副作用をデータ型として定義できます sealed trait LogicEffect[+A] case object Failure extends LogicEffect[Nothing] case object Choose extends LogicEffect[Boolean] case object Get extends LogicEffect[State] case class Put(state: State) extends LogicEffect[Unit]
  • 63. Algebraic Effects Logic is defined as an alias for Freer. LogicはFreerの別名として定義されます type Logic[A] = Freer[LogicEffect, A] def success[A](a: A): Logic[A] = Pure(a) def failure[A]: Logic[A] = Impure(Failure, Arrs.id)
  • 64. Algebraic Effects choose switches continuations with Boolean. chooseはBooleanによって継続を切り替えます def choose[A](x: Logic[A], y: Logic[A]): Logic[A] = Impure(Choose, Arrs.id).flatMap(if (_) x else y) def get: Logic[State] = Impure(Get, Arrs.id) def put(state: State): Logic[Unit] = Impure(Put(state), Arrs.id)
  • 65. Effect Handlers Logic can be handled as List. LogicはListとして処理できます def runList[A](logic: Logic[A], s: State): List[A] = logic match { case Pure(a) => List(a) case Impure(Failure, _) => Nil case Impure(Choose, k) => runList(s)(k(true)) ::: runList(s)(k(false)) case Impure(Get, k) => runList(s)(k(s)) case Impure(Put(s), k) => runList(s)(k(())) }
  • 66. Effect Handlers We can define various other effect handlers. • Handle in constant space asVector • Handle infinite solutions as Stream • Customize solution search algorithm 他にも様々なエフェクトハンドラを定義することができます
  • 67. Practical Applications Let's consider a practical application with Logic. It is good to have loops and conditionals. ここでLogicによる実践的なアプリケーションを考えます ループや条件分岐を含むものが良いです
  • 68. Practical Applications So it's Fizz Buzz. そこでFizz Buzzです def fizzbuzz(n: Int): Logic[String] = (n % 15 === 0).map(_ => "FizzBuzz") ||| (n % 3 === 0).map(_ => "Fizz") ||| (n % 5 === 0).map(_ => "Buzz") ||| success(n.toString)
  • 69. Practical Applications But there is a problem with this Fizz Buzz: The problem is that backtracking gives you all solutions. しかしこのFizzBuzzには問題があって、 バックトラッキングによって全ての解が得られてしまいます scala> println(run(fizzbuzz(15))) List(FizzBuzz, Fizz, Buzz, 15)
  • 70. Practical Applications Prolog solves the problem by using the cut operator. The cut operator can perform pruning and logical negation. Prologはcut演算子によりこの問題を解決しています cutは枝刈りや論理的な否定ができます
  • 71. Practical Applications There is one primitive to implement the functionality of the cut operator: cutの機能を実装するためのプリミティブがあります def split[A](logic: Logic[A]) : Logic[Option[(A, Logic[A])]]
  • 72. Practical Applications split is an operation that splits Logic into head and tail. If it can be split, it returns Some, otherwise it returns None. splitはLogicをheadとtailに分割します 分割できればSomeで返し、そうでないならNoneを返します
  • 73. Practical Applications Freer monads are good at partially handling side effects. The next slide shows the implementation. Freerモナドは副作用を部分的に処理することが得意です 次のスライドに実装を示します
  • 74. Practical Applications splitの実装です def split[A](logic: Logic[A]) = { def go(logic: Logic[A], state: State) = logic match { case Pure(a) => success(Some((a, failure))) case Impure(Failure, _) => success(None) case Impure(Choose, k) => go(k(true), state).map(_.map { case (a, t) => (a, t ||| k(false)) }) case Impure(Get, k) => go(k(state), state) case Impure(Put(state), k) => go(k(()), state) } get.flatMap(go(logic, _)) }
  • 75. Practical Applications We can define a conditional with split: splitで条件分岐を定義できます def ifte[A, B](logic: Logic[A])(th: A => Logic[B])(el: Logic[B]): Logic[B] = split(logic).flatMap { case None => el case Some((a, t)) => th(a) ||| t.flatMap(th) }
  • 76. Practical Applications Make useful operators. 便利な演算子を作って def orElse(that: => Logic[A]): Logic[A] = ifte(this)(success)(that)
  • 77. Practical Applications Rewrite Fizz Buzz. それで書き換えて def fizzbuzz(n: Int): Logic[String] = (n % 15 === 0).map(_ => "FizzBuzz") orElse (n % 3 === 0).map(_ => "Fizz") orElse (n % 5 === 0).map(_ => "Buzz") orElse success(n.toString)
  • 78. Practical Applications Perfect! 完璧です scala>val e3 = for { | n <- (1 to 15).foldMap(success) | s <- fizzbuzz(n) |} yield s scala> println(run(e3)) List(1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz)
  • 79. Conclusions • Logic Programming consists of Backtracking and Unification. • Backtracking computations is MonadPlus. • Freer monads and Type-aligned Sequence provide stack safety. • The representation of effects as data types can give different interpretations. 結論です
  • 80. References • https://github.com/halcat0x15a/logical • http://okmij.org/ftp/Computation/LogicT.pdf • http://okmij.org/ftp/Haskell/extensible/ more.pdf 参考文献です