Upgrade to Pro — share decks privately, control downloads, hide ads and more …

There's a Prolog in your Scala!

There's a Prolog in your Scala!

Video is available here: http://skillsmatter.com/podcast/scala/theres-a-prolog-in-your-scala

Visualizations from slides 33-34 are available here:
slide 33 (scala -> prolog): https://db.tt/pjVwnQuj
slide 34 (prolog -> scala): https://db.tt/R5NSJF5g

document from slide 7: http://www.foia.cia.gov/search-results?search_api_views_fulltext=SW+90-10029X&field_collection=

paper from slide 9: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.3972

DEMO repository: https://github.com/folone/scalaeXchange

Copyrights:
The photo of Battersea Power station: http://www.flickr.com/photos/stephenwalford/8420082569/
The photo of hanoi towers: http://www.flickr.com/photos/46268742@N00/8455144986/
The photo of Buran is taken from the following article: http://englishrussia.com/2006/09/14/buran-the-first-russian-shuttle/
Photo of Spock, played by Zachary Quinto, is presumably copyrighted by Paramount Pictures, Skydance Productions, and Bad Robot.

George Leontiev

December 02, 2013
Tweet

More Decks by George Leontiev

Other Decks in Technology

Transcript

  1. There is a Prolog
    in your Scala!
    @folone Scala eXchange ‘13

    View Slide

  2. One particular
    approach

    View Slide

  3. 8+ implicits
    FnHipsterAux

    View Slide

  4. Logic
    Programming

    View Slide

  5. programmation en
    logique, 1972, 5GL
    Lingua franca

    View Slide

  6. A language that doesn't
    affect the way you think
    about programming,
    is not worth knowing.
    — Alan J. Perlis

    View Slide

  7. Buran

    View Slide

  8. IBM Watson

    View Slide

  9. View Slide

  10. What > How
    Relations > Functions
    Facts
    Rules (to generate more facts)
    Main principles
    It's all about formulating the question.
    Expressed with

    View Slide

  11. Predicates > Functions
    Map inputs to outputs
    Run
    Return some output
    Define constraints
    Match
    Only return yes or no*
    *If "yes", they may add bindings to variables.
    log(2, 16, 4). log(2, 16) = 4

    View Slide

  12. — How many Prolog
    programmers does it take
    to change a lightbulb?

    View Slide

  13. — How many Prolog
    programmers does it take
    to change a lightbulb?
    NO.

    View Slide

  14. Scala eXchange
    tracks planning
    https://github.com/folone/scalaeXchange/

    View Slide

  15. Facts
    talk_about(dpp, webdev).
    talk_about(milessabin, typelevel).
    talk_about(larsr_h, typelevel).
    talk_about(xeno_by, macros).
    talk_about(milessabin, macros).
    talk_about(sirthias, webdev).

    View Slide

  16. Questions
    ?- talk_about(milessabin, webdev).
    no
    ?- talk_about(larsr_h, typelevel).
    yes
    ?- talk_about(dpp, X).
    X = webdev.
    ?- talk_about(milessabin, X).
    X = typelevel ;
    X = macros.

    View Slide

  17. Questions
    ?- talk_about(Who, What).
    Who = dpp, What = webdev ;
    Who = milessabin, What = typelevel ;
    Who = milessabin, What = macros ;
    Who = larsr_h, What = typelevel ;
    Who = xeno_by, What = macros ;
    Who = sirthias, What = webdev.

    View Slide

  18. Rules
    same_topic(Person1, Person2) :-
    talk_about(Person1, Topic),
    talk_about(Person2, Topic),
    Person1 \== Person2.
    ?- same_topic(milessabin, Who).
    Who = larsr_h ;
    Who = xeno_by.

    View Slide

  19. Facts
    works_in(dpp, industry).
    works_in(milessabin, industry).
    works_in(milessabin, academia).
    works_in(larsr_h, academia).
    works_in(xeno_by, academia).
    works_in(sirthias, industry).

    View Slide

  20. same_topic(Person1, Person2) :-
    talk_about(Person1, Topic),
    talk_about(Person2, Topic),
    Person1 \== Person2.
    same_topic(Person1, Person2) :-
    works_in(Person1, Area),
    works_in(Person2, Area),
    Person1 \== Person2.

    View Slide

  21. Questions
    ?- same_topic(dpp, Who).
    Who = sirthias ;
    Who = milessabin ;
    Who = sirthias.

    View Slide

  22. Rules
    exactly_same_topic(Person1, Person2) :-
    talk_about(Person1, Topic),
    talk_about(Person2, Topic),
    works_in(Person1, Area),
    works_in(Person2, Area),
    Person1 \== Person2.

    View Slide

  23. Questions
    ?- exactly_same_topic(dpp, Who).
    Who = sirthias.
    ?- exactly_same_topic(milessabin, Who).
    Who = larsr_h ;
    Who = xeno_by.

    View Slide

  24. topic(Topic, Res) :-
    findall(Person, talk_about(Person, Topic), L1),
    Res = (Topic, L1).
    environment(Area, Res) :-
    findall(Person, works_in(Person, Area), L1),
    Res = (Area, L1).
    ?- topic(webdev, List).
    List = (webdev, [dpp, sirthias]).
    ?- environment(academia, List).
    List = (academia, [milessabin, larsr_h, xeno_by]).

    View Slide

  25. topics(L) :-
    findall(Topic, talk_about(_, Topic), L1),
    list_to_set(L1, L).
    tracks(L) :-
    topics(L1),
    member(Topic, L1),
    topic(Topic, L).
    ?- topics(L).
    L = [webdev, typelevel, macros].
    ?- tracks(L).
    L = (webdev, [dpp, sirthias]) ;
    L = (typelevel, [milessabin, larsr_h]) ;
    L = (macros, [xeno_by, milessabin]).

    View Slide

  26. Functional is imperative without state.
    Logic is functional without manual search*.
    * DFS

    View Slide

  27. Scala is a logic
    programming language...

    View Slide

  28. in type system!
    Scala is a logic
    programming language...

    View Slide

  29. TYPELEVEL
    programming in Scala is...
    in type system!
    programming language...

    View Slide

  30. logic programming
    TYPELEVEL
    programming in Scala is...
    in type system!
    in Scala!

    View Slide

  31. Prolog
    gcd(X, X, X).
    gcd(X, Y, Out) :-
    X < Y
    Z is Y - X
    gcd(X, Z, Out).
    gcd(X, Y, Out) :-
    Y < X,
    gcd(Y, X, Out).

    View Slide

  32. trait GCD[X <: Nat, Y <: Nat] { type Out <: Nat }
    object GCD
    def gcd[N<:Nat](x:Nat,y:Nat)(implicit gcd:Aux[x.N,y.N,N],wn:Witness.Aux[N]):N =
    wn.value
    type Aux[X <: Nat, Y <: Nat, Z <: Nat] = GCD[X, Y] { type Out = Z }
    Scala
    {
    implicit def gcd0[X <: Nat]:
    Aux[X, X, X] =
    new GCD[X, X] { type Out = X }
    implicit def gcd1[X <: Nat, Y <: Nat, Z <: Nat,
    Out0 <: Nat]
    (implicit ev0 : LT[X, Y],
    ev1 : Diff.Aux[Y, X, Z],
    ev2 : Aux[X, Z, Out0]):
    Aux[X, Y, Out0] =
    new GCD[X, Y] { type Out = Out0 }
    implicit def gcd2[X <: Nat, Y <: Nat, Out0 <: Nat]
    (implicit ev0 : LT[Y, X],
    ev1 : Aux[Y, X, Out0]):
    Aux[X, Y, Out0] =
    new GCD[X, Y] { type Out = Out0}
    }

    View Slide

  33. View Slide

  34. View Slide

  35. Facts — implicit vals.
    Rules — implicit defs taking implicit
    vals as parameters.
    Implication is the other way around.

    View Slide

  36. Gotchas:
    • Scala does not perform the DFS. In case of
    multiple implicits, it does not compile. Prioritizing
    implicits via inheritance.
    • Diverging implicit expansion -Xlog-implicits.
    • Extremely hard to debug (pen and paper style).
    • Peculiar exceptions (SO in compiler, Method too
    large, etc.)

    View Slide

  37. — So now I need to redefine all the
    goodness from prolog stdlib?! Lists,
    naturals, etc.
    Shapeless: stdlib for logic programming
    in scala.

    View Slide

  38. DEMO
    https://github.com/folone/scalaeXchange/

    View Slide

  39. Functional in the small,
    OO in the large,
    logic in the type system!

    View Slide

  40. http://mitpress.mit.edu/books/art-prolog
    shapeless (and all the typelevel.scala libraries)
    metascala https://www.assembla.com/spaces/metascala/wiki
    Links

    View Slide

  41. @milessabin
    @xeno_by
    @travisbrown
    @larsr_h
    @killnicole
    Thanks

    View Slide

  42. ?-
    (λx.folonexlambda-calcul.us)@

    View Slide