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

Ruboty and SKI

pocke
January 31, 2020

Ruboty and SKI

pocke

January 31, 2020
Tweet

More Decks by pocke

Other Decks in Programming

Transcript

  1. Ruboty and
    SKI
    Meguro.rb #30
    2020-01-31 Fri.

    View Slide

  2. pp self
    ● Masataka “pocke” Kuwabara
    ● Work for BIt Journey, Inc.
    ● Live in ruby-jp.slack.com

    View Slide

  3. Agenda
    ● I implemented SKI combinator calculus with
    Ruboty, so I’ll describe the implemetation
    ○ What’s Ruboty
    ○ What’s SKI combinator calculus
    ○ How implement SKI combinator calculus in
    Ruboty

    View Slide

  4. What’s Ruboty

    View Slide

  5. Ruboty
    ● A chat bot framework written in Ruby
    ● https://github.com/r7kamura/ruboty
    ● Customizable by plugins written in Ruby
    ● Ruboty lives in ruby-jp.slack.com
    ○ Join us from https://ruby-jp.github.io/!
    ○ It is developed in
    https://github.com/pocke/ruboty-ruby-jp.

    View Slide

  6. Ruboty example

    View Slide

  7. What’s SKI combinator
    calculus

    View Slide

  8. I’m not sure!!!
    ● I’m not familiar with it
    ● But, I’ll try to describe it!
    ● Please give me advices if I’m wrong

    View Slide

  9. SKI combinator calculus
    ● A programming language (maybe)
    ● The program examples:
    ○ Ix, Kxy, Sxyz
    ○ S(K(SI))Kxy
    ● It replaces itself with 3 rules
    ○ The rules are S, K and I
    ● I’ll describe rule with reversed order
    ● It manipulates a string in this slide, but actually
    it manipulates a tree in general

    View Slide

  10. Rule I
    ● “I” takes one argument and returns it
    ● In other words, it’s just removed
    ● For example:
    ○ Ix => x
    ○ Iy => y
    ○ IIx => Ix => x
    ○ Ixyz => xyz
    ○ I(xyz) => xyz

    View Slide

  11. Rule K
    ● “K” takes two arguments and returns the first
    one
    ● For example:
    ○ Kxy => x
    ○ K(xyz)(abc) => xyz
    ○ Kixy => iy => y

    View Slide

  12. Rule S
    ● It takes three arguments, and returns “first
    third(second third)”
    ● For example:
    ○ Sxyz => xz(yz)
    ○ S(K(SI))Kxy => K(SI)x(Kx)y => SI(Kx)y =>
    Iy(Kxy) => y(Kxy) => yx

    View Slide

  13. How implement
    SKI combinator calculus in
    Ruboty

    View Slide

  14. The easiest way: Create a plugin
    ● We can create a plugin with writing the
    algorithm in Ruby
    ● But it is not interesting! It is too easy!
    ● So, I went to more difficult way

    View Slide

  15. More difficult way: Combination of plugins
    ● We can combine plugins to implement SKI
    combinator calculus
    ● I used taiki45/ruboty-echo and
    r7kamura/ruboty-replace
    ● I’ll describe these plguins

    View Slide

  16. ruboty-echo

    View Slide

  17. ruboty-echo
    ● “Ruboty repeats everything...”
    ● It’s super simple.
    ● ruboty echo hello
    ○ => Ruboty says “hello”

    View Slide

  18. HACK: ruboty reacts itself

    View Slide

  19. ruboty-replace

    View Slide

  20. ruboty-replace
    ● “Replace given message with registered
    patterns for other handlers.”
    ● Like alias
    ● example
    ○ ruboty replace hello (.+) with
    echo こんにちは \1 さん
    ○ “ruboty hello pocke”
    will be replaced with
    “ruboty echo こんにちは pocke さん”

    View Slide

  21. String#gsub!
    ● ruboty-replace just uses String#gsub!
    ● For example:
    ○ ruboty replace hello (.+) with
    echo こんにちは \1 さん
    ○ msg.gsub!(/hello (.+)/,
    “echo こんにちは \1 さん”)

    View Slide

  22. Combine them

    View Slide

  23. Make a loop (DO NOT TRY IT⚠)
    ● We can make an infinite loop with them easily
    ● Just say the following command⚠
    ○ ruboty replace loop with echo ruboty loop
    ● If you say “ruboty loop”,
    ruboty says “ruboty loop”,
    then ruboty says “ruboty loop”,
    then ruboty says “ruboty loop”,
    then ruboty says “ruboty loop”,
    then ruboty says “ruboty loop”,
    then ruboty says “ruboty loop”,

    View Slide

  24. It means we get “while” expression
    ● It equals “while true do … end”
    ● And, we already have String#gsub! by
    ruboty-replace
    ● If we can implement SKI only by “while” and
    gsub!, we can implement SKI with the plugins

    View Slide

  25. The regular expressions
    (?(?:[()]|[^ski])*)s(?[^()]|\(\g
    +\))(?[^()]|\(\g+\))(?[^()]|\(\g<
    expr3>+\))(?.*)
    (?(?:[()]|[^ski])*)k(?[^()]|\(\g
    +\))(?[^()]|\(\g+\))(?.*)$
    (?(?:[()]|[^ski])*)\((?(?[^()]
    |\(\g+\))*)\)(?.*)
    (?(?:[()]|[^ski])*)i(?.+)
    (?(?:[()]|[^ski])*)$
    (?.*[ski].*)$

    View Slide

  26. The result

    View Slide

  27. How create the
    regexps

    View Slide

  28. expr_gen
    expr_gen = -> (n) {
    "(?
    [^()] |
    \\(\\g+\\))
    "
    }
    ● Generate a string that matches an “expression”
    ● Recursive regexp by “\g”

    View Slide

  29. simple
    simple =
    '(?(?:
    [()] |
    [^ski])*)
    '
    ● String that matches simple string
    ● Simple string is not calculated

    View Slide

  30. I
    I = /^#{simple}i(?.+)/
    $i = '\k\k'

    View Slide

  31. K
    K =
    /^#{simple}k#{expr_gen.(1)}#{expr_ge
    n.(2)}(?.*)$/
    $k = '\k\k\k'

    View Slide

  32. S
    S =
    /^#{simple}s#{expr_gen.(1)}#{expr_ge
    n.(2)}#{expr_gen.(3)}(?.*)/
    $s =
    '\k(\k\k)(\kxpr2>\k)\k'

    View Slide

  33. Reduce parens
    P =
    /^#{simple}\((?#{expr_gen.(
    1)}*)\)(?.*)/
    $p = '\k\k\k'

    View Slide

  34. while and gsub!
    def ski(str)
    () while str.gsub!(S, $s) ||
    str.gsub!(K, $k) ||
    str.gsub!(I, $i) ||
    str.gsub!(P, $p)
    str
    end

    View Slide

  35. Conclusion

    View Slide

  36. Conclusion
    ● We learn Ruboty and SKI, and Regexp
    ● We can implement SKI in Slack without “code”
    ● For more information:
    ○ The Ruby program: https://bit.ly/2RI1Ckd
    ○ Japanese blog: https://bit.ly/2vs0fNE
    Thanks for listening!

    View Slide