SlideShare a Scribd company logo
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

Valoracion cardiovascular
Valoracion cardiovascularValoracion cardiovascular
Valoracion cardiovascular
Ricardo Garcia
 
Endoscopia GI y disfagia
Endoscopia GI y disfagiaEndoscopia GI y disfagia
Endoscopia GI y disfagia
Juan de Dios Díaz Rosales
 
Apendicitis Aguda
Apendicitis AgudaApendicitis Aguda
Apendicitis Aguda
enarm
 
Isquemia Aguda
Isquemia AgudaIsquemia Aguda
Isquemia Aguda
Pascual Lozano-Vilardell
 
Ruggiero saturacion venosa mixta y central
Ruggiero saturacion venosa mixta y centralRuggiero saturacion venosa mixta y central
Ruggiero saturacion venosa mixta y central
Residencia de Anestesiologia, Hospital San Martin de La Plata
 
Perforación esofago
Perforación esofagoPerforación esofago
Ecografías: ecodoppler y ecocardiografìa
Ecografías: ecodoppler y ecocardiografìaEcografías: ecodoppler y ecocardiografìa
Ecografías: ecodoppler y ecocardiografìa
Eduardo Sitja
 
EMC. Cirugía de las oclusiones agudas del intestino delgado en el adulto
EMC. Cirugía de las oclusiones agudas del intestino delgado en el adultoEMC. Cirugía de las oclusiones agudas del intestino delgado en el adulto
EMC. Cirugía de las oclusiones agudas del intestino delgado en el adulto
crazus
 
Hidatidosis
HidatidosisHidatidosis
Hidatidosis
Mercedes Calleja
 
Estudio clínico de Rowatinex
Estudio clínico de RowatinexEstudio clínico de Rowatinex
Estudio clínico de Rowatinex
Naturpharma (Medicina Biológica)
 
Hernias de pared
Hernias de paredHernias de pared
Hernias de pared
Josue Neri
 
Desfibriladores.pptx
Desfibriladores.pptxDesfibriladores.pptx
Desfibriladores.pptx
JesusEnriqueZapataMa
 
Ecocardiografia transesofagica
Ecocardiografia transesofagica Ecocardiografia transesofagica
Ecocardiografia transesofagica
Silvestre Degreéf
 

What's hot (13)

Valoracion cardiovascular
Valoracion cardiovascularValoracion cardiovascular
Valoracion cardiovascular
 
Endoscopia GI y disfagia
Endoscopia GI y disfagiaEndoscopia GI y disfagia
Endoscopia GI y disfagia
 
Apendicitis Aguda
Apendicitis AgudaApendicitis Aguda
Apendicitis Aguda
 
Isquemia Aguda
Isquemia AgudaIsquemia Aguda
Isquemia Aguda
 
Ruggiero saturacion venosa mixta y central
Ruggiero saturacion venosa mixta y centralRuggiero saturacion venosa mixta y central
Ruggiero saturacion venosa mixta y central
 
Perforación esofago
Perforación esofagoPerforación esofago
Perforación esofago
 
Ecografías: ecodoppler y ecocardiografìa
Ecografías: ecodoppler y ecocardiografìaEcografías: ecodoppler y ecocardiografìa
Ecografías: ecodoppler y ecocardiografìa
 
EMC. Cirugía de las oclusiones agudas del intestino delgado en el adulto
EMC. Cirugía de las oclusiones agudas del intestino delgado en el adultoEMC. Cirugía de las oclusiones agudas del intestino delgado en el adulto
EMC. Cirugía de las oclusiones agudas del intestino delgado en el adulto
 
Hidatidosis
HidatidosisHidatidosis
Hidatidosis
 
Estudio clínico de Rowatinex
Estudio clínico de RowatinexEstudio clínico de Rowatinex
Estudio clínico de Rowatinex
 
Hernias de pared
Hernias de paredHernias de pared
Hernias de pared
 
Desfibriladores.pptx
Desfibriladores.pptxDesfibriladores.pptx
Desfibriladores.pptx
 
Ecocardiografia transesofagica
Ecocardiografia transesofagica Ecocardiografia transesofagica
Ecocardiografia transesofagica
 

Similar to Making Logic Monad

Practical cats
Practical catsPractical cats
Practical cats
Raymond Tay
 
A brief introduction to apply functions
A brief introduction to apply functionsA brief introduction to apply functions
A brief introduction to apply functions
NIKET CHAURASIA
 
Functional Programming by Examples using Haskell
Functional Programming by Examples using HaskellFunctional Programming by Examples using Haskell
Functional Programming by Examples using Haskell
goncharenko
 
Loops and functions in r
Loops and functions in rLoops and functions in r
Loops and functions in r
manikanta361
 
Morel, a data-parallel programming language
Morel, a data-parallel programming languageMorel, a data-parallel programming language
Morel, a data-parallel programming language
Julian Hyde
 
Scala as a Declarative Language
Scala as a Declarative LanguageScala as a Declarative Language
Scala as a Declarative Language
vsssuresh
 
Morel, a Functional Query Language
Morel, a Functional Query LanguageMorel, a Functional Query Language
Morel, a Functional Query Language
Julian Hyde
 
Programming in R
Programming in RProgramming in R
Programming in R
Smruti Sarangi
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
Tomasz Kowalczewski
 
Frp2016 3
Frp2016 3Frp2016 3
Frp2016 3
Kirill Kozlov
 
Scala. Introduction to FP. Monads
Scala. Introduction to FP. MonadsScala. Introduction to FP. Monads
Scala. Introduction to FP. Monads
Kirill Kozlov
 
R Language Introduction
R Language IntroductionR Language Introduction
R Language Introduction
Khaled Al-Shamaa
 
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
Taisuke Oe
 
Real Time Big Data Management
Real Time Big Data ManagementReal Time Big Data Management
Real Time Big Data Management
Albert Bifet
 
Introduction to Matlab.pdf
Introduction to Matlab.pdfIntroduction to Matlab.pdf
Introduction to Matlab.pdf
ssuser43b38e
 
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 matlab
BilawalBaloch1
 
Fuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional ProgrammingFuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional Programming
Shine 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 Languages
Wim 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.0
Sheik 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

Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
IndexBug
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 
Infrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI modelsInfrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI models
Zilliz
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Mariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceXMariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceX
Mariano Tinti
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 

Recently uploaded (20)

Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial IntelligenceAI 101: An Introduction to the Basics and Impact of Artificial Intelligence
AI 101: An Introduction to the Basics and Impact of Artificial Intelligence
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 
Infrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI modelsInfrastructure Challenges in Scaling RAG with Custom AI models
Infrastructure Challenges in Scaling RAG with Custom AI models
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Mariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceXMariano G Tinti - Decoding SpaceX
Mariano G Tinti - Decoding SpaceX
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 

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 参考文献です