lernen 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +18 -0
  3. data/README.md +531 -28
  4. data/Rakefile +29 -7
  5. data/Steepfile +14 -0
  6. data/examples/ripper_prism.rb +63 -0
  7. data/examples/uri_parse_regexp.rb +73 -0
  8. data/lib/lernen/algorithm/cex_processor/acex.rb +43 -0
  9. data/lib/lernen/algorithm/cex_processor/prefix_transformer_acex.rb +43 -0
  10. data/lib/lernen/algorithm/cex_processor.rb +115 -0
  11. data/lib/lernen/algorithm/kearns_vazirani/discrimination_tree.rb +207 -0
  12. data/lib/lernen/algorithm/kearns_vazirani/kearns_vazirani_learner.rb +100 -0
  13. data/lib/lernen/algorithm/kearns_vazirani.rb +44 -0
  14. data/lib/lernen/algorithm/kearns_vazirani_vpa/discrimination_tree_vpa.rb +246 -0
  15. data/lib/lernen/algorithm/kearns_vazirani_vpa/kearns_vazirani_vpa_learner.rb +89 -0
  16. data/lib/lernen/algorithm/kearns_vazirani_vpa.rb +35 -0
  17. data/lib/lernen/algorithm/learner.rb +82 -0
  18. data/lib/lernen/algorithm/lsharp/lsharp_learner.rb +367 -0
  19. data/lib/lernen/algorithm/lsharp/observation_tree.rb +115 -0
  20. data/lib/lernen/algorithm/lsharp.rb +43 -0
  21. data/lib/lernen/algorithm/lstar/lstar_learner.rb +49 -0
  22. data/lib/lernen/algorithm/lstar/observation_table.rb +214 -0
  23. data/lib/lernen/algorithm/lstar.rb +49 -0
  24. data/lib/lernen/algorithm/procedural/atr_manager.rb +200 -0
  25. data/lib/lernen/algorithm/procedural/procedural_learner.rb +223 -0
  26. data/lib/lernen/algorithm/procedural/procedural_sul.rb +47 -0
  27. data/lib/lernen/algorithm/procedural/return_indices_acex.rb +58 -0
  28. data/lib/lernen/algorithm/procedural.rb +57 -0
  29. data/lib/lernen/algorithm.rb +19 -0
  30. data/lib/lernen/automaton/dfa.rb +204 -0
  31. data/lib/lernen/automaton/mealy.rb +108 -0
  32. data/lib/lernen/automaton/moore.rb +122 -0
  33. data/lib/lernen/automaton/moore_like.rb +83 -0
  34. data/lib/lernen/automaton/proc_util.rb +93 -0
  35. data/lib/lernen/automaton/spa.rb +368 -0
  36. data/lib/lernen/automaton/transition_system.rb +209 -0
  37. data/lib/lernen/automaton/vpa.rb +300 -0
  38. data/lib/lernen/automaton.rb +19 -92
  39. data/lib/lernen/equiv/combined_oracle.rb +57 -0
  40. data/lib/lernen/equiv/exhaustive_search_oracle.rb +60 -0
  41. data/lib/lernen/equiv/moore_like_simulator_oracle.rb +36 -0
  42. data/lib/lernen/equiv/oracle.rb +109 -0
  43. data/lib/lernen/equiv/random_walk_oracle.rb +69 -0
  44. data/lib/lernen/equiv/random_well_matched_word_oracle.rb +139 -0
  45. data/lib/lernen/equiv/random_word_oracle.rb +71 -0
  46. data/lib/lernen/equiv/spa_simulator_oracle.rb +39 -0
  47. data/lib/lernen/equiv/test_words_oracle.rb +42 -0
  48. data/lib/lernen/equiv/transition_system_simulator_oracle.rb +36 -0
  49. data/lib/lernen/equiv/vpa_simulator_oracle.rb +48 -0
  50. data/lib/lernen/equiv.rb +25 -0
  51. data/lib/lernen/graph.rb +215 -0
  52. data/lib/lernen/system/block_sul.rb +41 -0
  53. data/lib/lernen/system/moore_like_simulator.rb +45 -0
  54. data/lib/lernen/system/moore_like_sul.rb +33 -0
  55. data/lib/lernen/system/sul.rb +126 -0
  56. data/lib/lernen/system/transition_system_simulator.rb +40 -0
  57. data/lib/lernen/system.rb +72 -0
  58. data/lib/lernen/version.rb +2 -1
  59. data/lib/lernen.rb +322 -13
  60. data/rbs_collection.lock.yaml +16 -0
  61. data/rbs_collection.yaml +14 -0
  62. data/renovate.json +6 -0
  63. data/sig/generated/lernen/algorithm/cex_processor/acex.rbs +30 -0
  64. data/sig/generated/lernen/algorithm/cex_processor/prefix_transformer_acex.rbs +27 -0
  65. data/sig/generated/lernen/algorithm/cex_processor.rbs +59 -0
  66. data/sig/generated/lernen/algorithm/kearns_vazirani/discrimination_tree.rbs +68 -0
  67. data/sig/generated/lernen/algorithm/kearns_vazirani/kearns_vazirani_learner.rbs +51 -0
  68. data/sig/generated/lernen/algorithm/kearns_vazirani.rbs +32 -0
  69. data/sig/generated/lernen/algorithm/kearns_vazirani_vpa/discrimination_tree_vpa.rbs +73 -0
  70. data/sig/generated/lernen/algorithm/kearns_vazirani_vpa/kearns_vazirani_vpa_learner.rbs +51 -0
  71. data/sig/generated/lernen/algorithm/kearns_vazirani_vpa.rbs +20 -0
  72. data/sig/generated/lernen/algorithm/learner.rbs +53 -0
  73. data/sig/generated/lernen/algorithm/lsharp/lsharp_learner.rbs +103 -0
  74. data/sig/generated/lernen/algorithm/lsharp/observation_tree.rbs +53 -0
  75. data/sig/generated/lernen/algorithm/lsharp.rbs +38 -0
  76. data/sig/generated/lernen/algorithm/lstar/lstar_learner.rbs +38 -0
  77. data/sig/generated/lernen/algorithm/lstar/observation_table.rbs +79 -0
  78. data/sig/generated/lernen/algorithm/lstar.rbs +37 -0
  79. data/sig/generated/lernen/algorithm/procedural/atr_manager.rbs +80 -0
  80. data/sig/generated/lernen/algorithm/procedural/procedural_learner.rbs +79 -0
  81. data/sig/generated/lernen/algorithm/procedural/procedural_sul.rbs +36 -0
  82. data/sig/generated/lernen/algorithm/procedural/return_indices_acex.rbs +33 -0
  83. data/sig/generated/lernen/algorithm/procedural.rbs +27 -0
  84. data/sig/generated/lernen/algorithm.rbs +10 -0
  85. data/sig/generated/lernen/automaton/dfa.rbs +93 -0
  86. data/sig/generated/lernen/automaton/mealy.rbs +61 -0
  87. data/sig/generated/lernen/automaton/moore.rbs +69 -0
  88. data/sig/generated/lernen/automaton/moore_like.rbs +63 -0
  89. data/sig/generated/lernen/automaton/proc_util.rbs +38 -0
  90. data/sig/generated/lernen/automaton/spa.rbs +125 -0
  91. data/sig/generated/lernen/automaton/transition_system.rbs +108 -0
  92. data/sig/generated/lernen/automaton/vpa.rbs +109 -0
  93. data/sig/generated/lernen/automaton.rbs +15 -0
  94. data/sig/generated/lernen/equiv/combined_oracle.rbs +27 -0
  95. data/sig/generated/lernen/equiv/exhaustive_search_oracle.rbs +38 -0
  96. data/sig/generated/lernen/equiv/moore_like_simulator_oracle.rbs +27 -0
  97. data/sig/generated/lernen/equiv/oracle.rbs +75 -0
  98. data/sig/generated/lernen/equiv/random_walk_oracle.rbs +41 -0
  99. data/sig/generated/lernen/equiv/random_well_matched_word_oracle.rbs +70 -0
  100. data/sig/generated/lernen/equiv/random_word_oracle.rbs +45 -0
  101. data/sig/generated/lernen/equiv/spa_simulator_oracle.rbs +30 -0
  102. data/sig/generated/lernen/equiv/test_words_oracle.rbs +20 -0
  103. data/sig/generated/lernen/equiv/transition_system_simulator_oracle.rbs +27 -0
  104. data/sig/generated/lernen/equiv/vpa_simulator_oracle.rbs +33 -0
  105. data/sig/generated/lernen/equiv.rbs +11 -0
  106. data/sig/generated/lernen/graph.rbs +80 -0
  107. data/sig/generated/lernen/system/block_sul.rbs +29 -0
  108. data/sig/generated/lernen/system/moore_like_simulator.rbs +31 -0
  109. data/sig/generated/lernen/system/moore_like_sul.rbs +28 -0
  110. data/sig/generated/lernen/system/sul.rbs +87 -0
  111. data/sig/generated/lernen/system/transition_system_simulator.rbs +28 -0
  112. data/sig/generated/lernen/system.rbs +62 -0
  113. data/sig/generated/lernen/version.rbs +6 -0
  114. data/sig/generated/lernen.rbs +214 -0
  115. data/sig-test/generated/test/example_test.rbs +14 -0
  116. data/sig-test/generated/test/lernen/algorithm/kearns_vazirani_test.rbs +16 -0
  117. data/sig-test/generated/test/lernen/algorithm/kearns_vazirani_vpa_test.rbs +10 -0
  118. data/sig-test/generated/test/lernen/algorithm/lsharp_test.rbs +16 -0
  119. data/sig-test/generated/test/lernen/algorithm/lstar_test.rbs +16 -0
  120. data/sig-test/generated/test/lernen/algorithm/procedural_test.rbs +10 -0
  121. data/sig-test/generated/test/lernen/automaton/dfa_test.rbs +19 -0
  122. data/sig-test/generated/test/lernen/automaton/mealy_test.rbs +19 -0
  123. data/sig-test/generated/test/lernen/automaton/moore_test.rbs +19 -0
  124. data/sig-test/generated/test/lernen/automaton/proc_util_test.rbs +19 -0
  125. data/sig-test/generated/test/lernen/automaton/spa_test.rbs +19 -0
  126. data/sig-test/generated/test/lernen/automaton/vpa_test.rbs +19 -0
  127. data/sig-test/generated/test/lernen/equiv/exhaustive_search_oracle_test.rbs +10 -0
  128. data/sig-test/generated/test/lernen/equiv/random_walk_oracle_test.rbs +10 -0
  129. data/sig-test/generated/test/lernen/equiv/random_word_oracle_test.rbs +10 -0
  130. data/sig-test/generated/test/lernen/system/block_sul_test.rbs +16 -0
  131. data/sig-test/generated/test/lernen/system/moore_like_simulator_test.rbs +16 -0
  132. data/sig-test/generated/test/lernen/system/transition_system_simulator_test.rbs +13 -0
  133. data/sig-test/generated/test/lernen/system_test.rbs +11 -0
  134. data/sig-test/generated/test/lernen_test.rbs +13 -0
  135. metadata +131 -11
  136. data/.yardopts +0 -3
  137. data/lib/lernen/cex_processor.rb +0 -61
  138. data/lib/lernen/kearns_vazirani.rb +0 -199
  139. data/lib/lernen/lsharp.rb +0 -335
  140. data/lib/lernen/lstar.rb +0 -169
  141. data/lib/lernen/oracle.rb +0 -116
  142. data/lib/lernen/sul.rb +0 -134
@@ -0,0 +1,11 @@
1
+ # Generated from lib/lernen/equiv.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ # This is a namespace for equivalence query oracles.
5
+ #
6
+ # A equivalence query check the given hypothesis automaton is equivalence
7
+ # to a SUL. If that is not, it returns a counterexample, which leads
8
+ # different output values between the hypothesis and the SUL.
9
+ module Equiv
10
+ end
11
+ end
@@ -0,0 +1,80 @@
1
+ # Generated from lib/lernen/graph.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ # Graph represents a labelled directed graph.
5
+ #
6
+ # This is an intermediate data structure for rendering Mermaid and Graphviz diagrams.
7
+ class Graph
8
+ type node_shape = :circle | :doublecircle
9
+
10
+ type mermaid_direction = "TD" | "DT" | "LR" | "RL"
11
+
12
+ class Node < Data
13
+ attr_reader label: String
14
+ attr_reader shape: node_shape
15
+ def self.[]: (String label, node_shape shape) -> Node
16
+ end
17
+
18
+ class Edge < Data
19
+ attr_reader from: Integer
20
+ attr_reader label: String
21
+ attr_reader to: Integer
22
+ def self.[]: (Integer from, String label, Integer to) -> Edge
23
+ end
24
+
25
+ class SubGraph < Data
26
+ attr_reader label: String
27
+ attr_reader graph: Graph
28
+ def self.[]: (String label, Graph graph) -> SubGraph
29
+ end
30
+
31
+ # Returns the escaped string for Mermaid diagrams.
32
+ #
33
+ # See https://mermaid.js.org/syntax/flowchart.html#entity-codes-to-escape-characters.
34
+ #
35
+ # : (String label) -> String
36
+ def self.mermaid_escape: (String label) -> String
37
+
38
+ # Returns the escaped string for GraphViz DOTs.
39
+ #
40
+ # See https://graphviz.org/docs/attr-types/escString/.
41
+ #
42
+ # : (String label) -> String
43
+ def self.dot_escape: (String label) -> String
44
+
45
+ @subgraphs: Array[SubGraph]
46
+
47
+ @edges: Array[Edge]
48
+
49
+ @nodes: Hash[Integer, Node]
50
+
51
+ # : (
52
+ # Hash[Integer, Node] nodes,
53
+ # Array[Edge] edges,
54
+ # ?Array[SubGraph] subgraphs
55
+ # ) -> void
56
+ def initialize: (Hash[Integer, Node] nodes, Array[Edge] edges, ?Array[SubGraph] subgraphs) -> void
57
+
58
+ attr_reader nodes: Hash[Integer, Node]
59
+
60
+ attr_reader edges: Array[Edge]
61
+
62
+ attr_reader subgraphs: Array[SubGraph]
63
+
64
+ # Returns a [Mermaid](https://mermaid.js.org) diagram of this graph.
65
+ #
66
+ # : (?direction: mermaid_direction) -> String
67
+ def to_mermaid: (?direction: mermaid_direction) -> String
68
+
69
+ # Returns a [GraphViz](https://graphviz.org) DOT diagram of this graph.
70
+ #
71
+ # : () -> String
72
+ def to_dot: () -> String
73
+
74
+ # : (?String id_prefix) -> String
75
+ def to_mermaid_internal: (?String id_prefix) -> String
76
+
77
+ # : (?String id_prefix) -> String
78
+ def to_dot_internal: (?String id_prefix) -> String
79
+ end
80
+ end
@@ -0,0 +1,29 @@
1
+ # Generated from lib/lernen/system/block_sul.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ module System
5
+ # BlockSUL is a system under learning (SUL) constructed from a block.
6
+ #
7
+ # A block is expected to behave like a membership query.
8
+ #
9
+ # @rbs generic In -- Type for input alphabet
10
+ # @rbs generic Out -- Type for output values
11
+ class BlockSUL[In, Out] < MooreLikeSUL[In, Out]
12
+ @block: ^(Array[In]) -> Out
13
+
14
+ @word: Array[In]
15
+
16
+ # : (?cache: bool) { (Array[In]) -> Out } -> void
17
+ def initialize: (?cache: bool) { (Array[In]) -> Out } -> void
18
+
19
+ # @rbs override
20
+ def setup: ...
21
+
22
+ # @rbs override
23
+ def step: ...
24
+
25
+ # @rbs override
26
+ def query_empty: ...
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ # Generated from lib/lernen/system/moore_like_simulator.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ module System
5
+ # MooreLikeSimulator is a system under learning (SUL) using a Moore-like machine simulation.
6
+ #
7
+ # @rbs generic Conf -- Type for a configuration of this automaton
8
+ # @rbs generic In -- Type for input alphabet
9
+ # @rbs generic Out -- Type for output values
10
+ class MooreLikeSimulator[Conf, In, Out] < MooreLikeSUL[In, Out]
11
+ @automaton: Automaton::MooreLike[Conf, In, Out]
12
+
13
+ @current_conf: Conf | nil
14
+
15
+ # : (Automaton::MooreLike[Conf, In, Out] automaton, ?cache: bool) -> void
16
+ def initialize: (Automaton::MooreLike[Conf, In, Out] automaton, ?cache: bool) -> void
17
+
18
+ # @rbs override
19
+ def setup: ...
20
+
21
+ # @rbs override
22
+ def shutdown: ...
23
+
24
+ # @rbs override
25
+ def step: ...
26
+
27
+ # @rbs override
28
+ def query_empty: ...
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ # Generated from lib/lernen/system/moore_like_sul.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ module System
5
+ # MooreLikeSUL is a system under learning (SUL) for a system much like Moore machine.
6
+ #
7
+ # By contrast to `SUL`, this accepts a query with the empty string additionally.
8
+ #
9
+ # Note that this class is *abstract*. You should implement the following method:
10
+ #
11
+ # - `#step(input)`
12
+ # - `#query_empty`
13
+ #
14
+ # @rbs generic In -- Type for input alphabet
15
+ # @rbs generic Out -- Type for output values
16
+ class MooreLikeSUL[In, Out] < SUL[In, Out]
17
+ # : (?cache: bool) -> void
18
+ def initialize: (?cache: bool) -> void
19
+
20
+ # Runs a membership query with the empty input.
21
+ #
22
+ # This is an abstract method.
23
+ #
24
+ # : () -> Out
25
+ def query_empty: () -> Out
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,87 @@
1
+ # Generated from lib/lernen/system/sul.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ module System
5
+ # SUL represents a system under learning.
6
+ #
7
+ # It is an abtraction of a system under learning (SUL) which accepts an operation
8
+ # called "membership query"; it takes an input string (word) and returns a sequence
9
+ # of outputs corresponding to the input string.
10
+ #
11
+ # This SUL assumes the system is much like Mealy machine; that is, a transition puts
12
+ # an output, and query does not accept the empty string due to no outputs.
13
+ #
14
+ # This SUL also implements cache mechanism. The cache mechanism is enabled by the default,
15
+ # and it can be disabled by specifying `cache: false`.
16
+ #
17
+ # On running a SUL, this SUL records the statistics information. We can obtain this
18
+ # information by `SUL#stats`.
19
+ #
20
+ # Note that this class is *abstract*. You should implement the following method:
21
+ #
22
+ # - `#step(input)`
23
+ #
24
+ # @rbs generic In -- Type for input alphabet
25
+ # @rbs generic Out -- Type for output values
26
+ class SUL[In, Out]
27
+ @cache: Hash[Array[In], Array[Out]] | nil
28
+
29
+ @num_cached_queries: Integer
30
+
31
+ @num_queries: Integer
32
+
33
+ @num_steps: Integer
34
+
35
+ # : (?cache: bool) -> void
36
+ def initialize: (?cache: bool) -> void
37
+
38
+ # Returns the statistics information as a `Hash` object.
39
+ #
40
+ # The result hash contains the following values.
41
+ #
42
+ # - `num_cache`: The number of cached queries.
43
+ # - `num_cached_queries`: The number of queries uses the cache.
44
+ # - `num_queries`: The number of (non-cached) queries.
45
+ # - `num_steps`: The total number of steps.
46
+ #
47
+ # : () -> Hash[Symbol, Integer]
48
+ def stats: () -> Hash[Symbol, Integer]
49
+
50
+ # Runs a membership query with the given word.
51
+ #
52
+ # Note that this method does not accept the empty string due to no outpus.
53
+ # If you need to call `query` with the empty string, you should use `MooreSUL#query_empty` instead.
54
+ #
55
+ # : (Array[In] word) -> Array[Out]
56
+ def query: (Array[In] word) -> Array[Out]
57
+
58
+ # Runs a membership query with the given word, and returns the last output.
59
+ #
60
+ # It is the same as `query(word).last`.
61
+ #
62
+ # : (Array[In] word) -> Out
63
+ def query_last: (Array[In] word) -> Out
64
+
65
+ # It is a setup procedure of this SUL.
66
+ #
67
+ # Note that it does nothing by default.
68
+ #
69
+ # : () -> void
70
+ def setup: () -> void
71
+
72
+ # It is a shutdown procedure of this SUL.
73
+ #
74
+ # Note that it does nothing by default.
75
+ #
76
+ # : () -> void
77
+ def shutdown: () -> void
78
+
79
+ # Consumes the given `input` and returns the correspoding output.
80
+ #
81
+ # This is an abstract method.
82
+ #
83
+ # : (In input) -> Out
84
+ def step: (In input) -> Out
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,28 @@
1
+ # Generated from lib/lernen/system/transition_system_simulator.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ module System
5
+ # TransitionSystemSimulator is a system under learning (SUL) using a transition system simulation.
6
+ #
7
+ # @rbs generic Conf -- Type for a configuration of this automaton
8
+ # @rbs generic In -- Type for input alphabet
9
+ # @rbs generic Out -- Type for output values
10
+ class TransitionSystemSimulator[Conf, In, Out] < SUL[In, Out]
11
+ @automaton: Automaton::TransitionSystem[Conf, In, Out]
12
+
13
+ @current_conf: Conf | nil
14
+
15
+ # : (Automaton::TransitionSystem[Conf, In, Out] automaton, ?cache: bool) -> void
16
+ def initialize: (Automaton::TransitionSystem[Conf, In, Out] automaton, ?cache: bool) -> void
17
+
18
+ # @rbs override
19
+ def setup: ...
20
+
21
+ # @rbs override
22
+ def shutdown: ...
23
+
24
+ # @rbs override
25
+ def step: ...
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,62 @@
1
+ # Generated from lib/lernen/system.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ # This is a namespace for systems under learning (SULs).
5
+ #
6
+ # `SUL` is an implementation of membership (or output) query.
7
+ #
8
+ # There are two base abstract classes of SULs: `SUL` and `MooreLikeSUL`
9
+ # `SUL` is the most base abstract class of SULs and it cannot answer a query
10
+ # with the empty string. `MooreLikeSUL` is subclass of `SUL` and it can answer
11
+ # the empty string query.
12
+ #
13
+ # In this library, we provide two easy ways to create a SUL. The first way is
14
+ # `System.from_block`. This method takes a block, and the block is used as
15
+ # a membership query implementation.
16
+ #
17
+ # ```ruby
18
+ # sul = Lernen::System.from_block do |word|
19
+ # word.count("1") % 4 == 3
20
+ # end
21
+ # ```
22
+ #
23
+ # The another way is `System.from_automaton`. This method takes an automaton
24
+ # (a transition system), and the result SUL simulates this automaton.
25
+ #
26
+ # ```ruby
27
+ # dfa = Lernen::Automaton::DFA.new(
28
+ # 0,
29
+ # Set[1],
30
+ # {
31
+ # [0, '0'] => 0,
32
+ # [0, '1'] => 1,
33
+ # [1, '0'] => 1,
34
+ # [1, '1'] => 1,
35
+ # }
36
+ # )
37
+ #
38
+ # sul = Lernen::System.from_automaton(dfa)
39
+ # ```
40
+ module System
41
+ # Creates a SUL from the given block as an implementation of a membership query.
42
+ #
43
+ # : [In, Out] (?cache: bool) { (Array[In]) -> Out } -> MooreLikeSUL[In, Out]
44
+ def self.from_block: [In, Out] (?cache: bool) { (Array[In]) -> Out } -> MooreLikeSUL[In, Out]
45
+
46
+ # Creates a SUL from the given automaton as an implementation.
47
+ #
48
+ # This method chooses a suitable SUL implementation, which is one of `TransitionSystemSimulator`
49
+ # or `MooreLikeSimulator`, for the given automaton.
50
+ #
51
+ # : [In] (Automaton::DFA[In] automaton, ?cache: bool) -> SUL[In, bool]
52
+ # : [In, Out] (Automaton::Mealy[In, Out] automaton, ?cache: bool) -> SUL[In, Out]
53
+ # : [In, Out] (Automaton::Moore[In, Out] automaton, ?cache: bool) -> SUL[In, Out]
54
+ # : [In, Call, Return] (Automaton::VPA[In, Call, Return] automaton, ?cache: bool) -> SUL[In | Call | Return, bool]
55
+ # : [In, Call, Return] (Automaton::SPA[In, Call, Return] automaton, ?cache: bool) -> SUL[In | Call | Return, bool]
56
+ def self.from_automaton: [In] (Automaton::DFA[In] automaton, ?cache: bool) -> SUL[In, bool]
57
+ | [In, Out] (Automaton::Mealy[In, Out] automaton, ?cache: bool) -> SUL[In, Out]
58
+ | [In, Out] (Automaton::Moore[In, Out] automaton, ?cache: bool) -> SUL[In, Out]
59
+ | [In, Call, Return] (Automaton::VPA[In, Call, Return] automaton, ?cache: bool) -> SUL[In | Call | Return, bool]
60
+ | [In, Call, Return] (Automaton::SPA[In, Call, Return] automaton, ?cache: bool) -> SUL[In | Call | Return, bool]
61
+ end
62
+ end
@@ -0,0 +1,6 @@
1
+ # Generated from lib/lernen/version.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ # The version string.
5
+ VERSION: ::String
6
+ end
@@ -0,0 +1,214 @@
1
+ # Generated from lib/lernen.rb with RBS::Inline
2
+
3
+ # Lernen is an automata learning library written in Ruby.
4
+ #
5
+ # **Automata learning** (active automata learning) is a known technique to infer an automaton
6
+ # from a teacher program; here, a teacher is an abstraction of a system (or a program) that
7
+ # can answer two kinds of queries. One kind of queries is **membership** query, which takes
8
+ # an input word and returns a boolean value whether the word is accepted or rejected by the system.
9
+ # Another kind of queries is **equivalence** query, which takes a hypothesis (under-learning) automaton
10
+ # and returns `true` if the hypothesis is equivalent to the system, or returns a counterexample
11
+ # word if it is not equivalent. Automata learning algorithms use these queries to gather
12
+ # information about the black-box system and infer an automaton which is equivalent to the system.
13
+ #
14
+ # This library implements some automata learning algorithms.
15
+ #
16
+ # - L* (also known as Angluin's L*) is a common and classic algorithm for automata learning, introduced
17
+ # by [Angluin (1987) "Learning Regular Sets from Queries and Counterexamples"](https://dl.acm.org/doi/10.1016/0890-5401%2887%2990052-6).
18
+ # This algorithm uses an observation table for collecting query results and inferring an automaton.
19
+ # Our implementation also accepts the Rivest-Schapire counterexample processing optimization described by
20
+ # [Rivest & Schapire (1993) "Inference of Finite Automata Using Homing Sequences"](https://www.sciencedirect.com/science/article/pii/S0890540183710217).
21
+ # - Kearns-Vazirani is also a common and classic algorithm, introduced by
22
+ # [Kearns & Vazirani (1994) "An Introduction to Computational Learning Theory"](https://direct.mit.edu/books/monograph/2604/An-Introduction-to-Computational-Learning-Theory).
23
+ # This algorithm uses a discrimination tree for learning an automaton instead of an observation
24
+ # tree. Also, our implementation is extended to infer a VPA (visibly pushdown automaton) that is
25
+ # an extension of DFA which can recognize some non-regular languages (nested words).
26
+ # It is the default algorithm in this library.
27
+ # - L# is a modern algorithm for automata learning, introduced by
28
+ # [Vaandrager et al. (2022) "A New Approach for Active Automata Learning Based on Apartness"](https://link.springer.com/chapter/10.1007/978-3-030-99524-9_12).
29
+ # This algorithm uses apartness relation and an observation tree for learning an automaton.
30
+ # In many cases, it reduces the numbers of queries, but the data structure and algorithm have
31
+ # some overheads. If a query is slow (e.g., forking a process), this algorithm may be a good option.
32
+ #
33
+ # ## Example
34
+ #
35
+ # This library provides `Lernen.learn` method as a good frontend for learning an automaton.
36
+ #
37
+ # In the most simple way to use it, we need to give `alphabet` and a block to infer a program
38
+ # to `Lernen.learn`. See the below example. This example is a program to learn a prediction on
39
+ # the binary language as a DFA and print it as a [mermaid](https://mermaid.js.org) diagram.
40
+ #
41
+ # ```ruby
42
+ # dfa = Lernen.learn(alphabet: %w[0 1]) do |word|
43
+ # word.count("1") % 4 == 3
44
+ # end
45
+ # puts dfa.to_mermaid
46
+ #
47
+ # # Output:
48
+ # # flowchart TD
49
+ # # 0((0))
50
+ # # 1((1))
51
+ # # 2((2))
52
+ # # 3(((3)))
53
+ # #
54
+ # # 0 -- "'0'" --> 0
55
+ # # 0 -- "'1'" --> 1
56
+ # # 1 -- "'0'" --> 1
57
+ # # 1 -- "'1'" --> 2
58
+ # # 2 -- "'0'" --> 2
59
+ # # 2 -- "'1'" --> 3
60
+ # # 3 -- "'0'" --> 3
61
+ # # 3 -- "'1'" --> 0
62
+ # ```
63
+ #
64
+ # Of course, we can specify more parameters to `Lernen.learn` for learning other kinds of automata
65
+ # such as Moore or Mealy machines. Please refer the `Lernen.learn` doc.
66
+ module Lernen
67
+ type oracle_type = :exhaustive_search | :random_walk | :random_word | :random_well_matched_word | :simulator
68
+
69
+ type algorithm_name = :lstar | :kearns_vazirani | :lsharp
70
+
71
+ # Learn an automaton by using the given parameters.
72
+ #
73
+ # This method is a frontend of the learning algorithms. Actual implementations are placed under
74
+ # the `Lernen::Algorithm` namespace.
75
+ #
76
+ # ## Parameters
77
+ #
78
+ # This method takes a lot of parameters, but almost of parameters are optional. To start learning,
79
+ # we need to give `alphabet` and a block of a program to infer an automaton.
80
+ #
81
+ # - `alphabet`: An input alphabet. This must be given as an `Array` object.
82
+ # - `call_alphabet`: A call input alphabet of VPA. If this is specified, `automaton_type` is specified
83
+ # as `:vpa` automatically.
84
+ # - `return_alphabet`: A return input alphabet of VPA.
85
+ # - `sul`: A system under learning. If an automaton instance is given, it is converted it to a simulator
86
+ # and use it as a SUL. Or, if it is not specified, we use a block as a SUL.
87
+ # - `oracle`: An equivalence oracle. It is one of `:exhaustive_search`, `:random_walk`, `:random_word`, or
88
+ # an actual instance of `Equiv::Oracle`. If the value is a symbol, an `Equiv::Oracle` instance of the specified
89
+ # kind is created with `oracle_params`. The default value is `:random_word` if `automaton_type` is one of `:dfa`,
90
+ # `:moore`, and `:mealy`, or the default value is `:random_well_matched_word` if `automaton_type` is either `:spa`
91
+ # or `:vpa`.
92
+ # - `oracle_params`: A hash of parameters for equivalence oracle. The default value is `{}`.
93
+ # - `algorithm`: An algorithm name to use. It is one of `:lstar`, `:kearns_vazirani`, or `:lsharp`. The default value
94
+ # is `:kearns_vazirani` (if `automaton_type` is one of `:dfa`, `:moore`, and `:mealy`), or `:kearns_vazirani_vpa`
95
+ # (if `automaton_type` is `vpa`), or `:procedural` (if `automaton_type` is `spa`).
96
+ # - `automaton_type`: A type of automaton to infer. It is one of `:dfa`, `:mealy`, `:moore`, `:vpa`, and `:spa`.
97
+ # The default value is `:dfa`, but it becomes `:vpa` or `:spa` if `call_alphabet` or `return_input` is specified.
98
+ # - `params`: A hash of parameter to pass a learning algorithm. The default value is `{}`.
99
+ # - `random`: A PRNG instance. It is used by an equivalence oracle.
100
+ #
101
+ # : [In] (
102
+ # alphabet: Array[In],
103
+ # sul: Automaton::DFA[In] | System::MooreLikeSUL[In, bool],
104
+ # ?oracle: oracle_type | Equiv::Oracle[In, bool],
105
+ # ?oracle_params: Hash[Symbol, untyped],
106
+ # ?algorithm: algorithm_name,
107
+ # ?automaton_type: :dfa,
108
+ # ?params: Hash[Symbol, untyped],
109
+ # ?random: Random
110
+ # ) -> Automaton::DFA[In]
111
+ # : [In] (
112
+ # alphabet: Array[In],
113
+ # ?oracle: oracle_type | Equiv::Oracle[In, bool],
114
+ # ?oracle_params: Hash[Symbol, untyped],
115
+ # ?algorithm: algorithm_name,
116
+ # ?automaton_type: :dfa,
117
+ # ?params: Hash[Symbol, untyped],
118
+ # ?random: Random
119
+ # ) { (Array[In]) -> bool } -> Automaton::DFA[In]
120
+ # : [In, Out] (
121
+ # alphabet: Array[In],
122
+ # sul: Automaton::Mealy[In, Out] | System::SUL[In, Out],
123
+ # ?oracle: oracle_type | Equiv::Oracle[In, Out],
124
+ # ?oracle_params: Hash[Symbol, untyped],
125
+ # ?algorithm: algorithm_name,
126
+ # automaton_type: :mealy,
127
+ # ?params: Hash[Symbol, untyped],
128
+ # ?random: Random
129
+ # ) -> Automaton::Mealy[In, Out]
130
+ # : [In, Out] (
131
+ # alphabet: Array[In],
132
+ # ?oracle: oracle_type | Equiv::Oracle[In, Out],
133
+ # ?oracle_params: Hash[Symbol, untyped],
134
+ # ?algorithm: algorithm_name,
135
+ # automaton_type: :mealy,
136
+ # ?params: Hash[Symbol, untyped],
137
+ # ?random: Random
138
+ # ) { (Array[In]) -> Out } -> Automaton::Mealy[In, Out]
139
+ # : [In, Out] (
140
+ # alphabet: Array[In],
141
+ # sul: Automaton::Moore[In, Out] | System::MooreLikeSUL[In, Out],
142
+ # ?oracle: oracle_type | Equiv::Oracle[In, Out],
143
+ # ?oracle_params: Hash[Symbol, untyped],
144
+ # ?algorithm: algorithm_name,
145
+ # automaton_type: :moore,
146
+ # ?params: Hash[Symbol, untyped],
147
+ # ?random: Random
148
+ # ) -> Automaton::Moore[In, Out]
149
+ # : [In, Out] (
150
+ # alphabet: Array[In],
151
+ # ?oracle: oracle_type | Equiv::Oracle[In, Out],
152
+ # ?oracle_params: Hash[Symbol, untyped],
153
+ # ?algorithm: algorithm_name,
154
+ # automaton_type: :moore,
155
+ # ?params: Hash[Symbol, untyped],
156
+ # ?random: Random
157
+ # ) { (Array[In]) -> Out } -> Automaton::Moore[In, Out]
158
+ # : [In, Call, Return] (
159
+ # alphabet: Array[In],
160
+ # call_alphabet: Array[Call],
161
+ # return_alphabet: Array[Return],
162
+ # sul: Automaton::VPA[In, Call, Return] | System::MooreLikeSUL[In | Call | Return, bool],
163
+ # ?oracle: oracle_type | Equiv::Oracle[In | Call | Return, bool],
164
+ # ?oracle_params: Hash[Symbol, untyped],
165
+ # ?algorithm: :kearns_vazirani_vpa,
166
+ # ?automaton_type: :vpa,
167
+ # ?params: Hash[Symbol, untyped],
168
+ # ?random: Random
169
+ # ) -> Automaton::VPA[In, Call, Return]
170
+ # : [In, Call, Return] (
171
+ # alphabet: Array[In],
172
+ # call_alphabet: Array[Call],
173
+ # return_alphabet: Array[Return],
174
+ # ?oracle: oracle_type | Equiv::Oracle[In | Call | Return, bool],
175
+ # ?oracle_params: Hash[Symbol, untyped],
176
+ # ?algorithm: :kearns_vazirani_vpa,
177
+ # ?automaton_type: :vpa,
178
+ # ?params: Hash[Symbol, untyped],
179
+ # ?random: Random
180
+ # ) { (Array[In | Call | Return]) -> bool } -> Automaton::VPA[In, Call, Return]
181
+ # : [In, Call, Return] (
182
+ # alphabet: Array[In],
183
+ # call_alphabet: Array[Call],
184
+ # return_input: Return,
185
+ # sul: Automaton::SPA[In, Call, Return] | System::MooreLikeSUL[In | Call | Return, bool],
186
+ # ?oracle: oracle_type | Equiv::Oracle[In | Call | Return, bool],
187
+ # ?oracle_params: Hash[Symbol, untyped],
188
+ # ?algorithm: :procedural,
189
+ # ?automaton_type: :spa,
190
+ # ?params: Hash[Symbol, untyped],
191
+ # ?random: Random
192
+ # ) -> Automaton::SPA[In, Call, Return]
193
+ # : [In, Call, Return] (
194
+ # alphabet: Array[In],
195
+ # call_alphabet: Array[Call],
196
+ # return_input: Return,
197
+ # ?oracle: oracle_type | Equiv::Oracle[In | Call | Return, bool],
198
+ # ?oracle_params: Hash[Symbol, untyped],
199
+ # ?algorithm: :procedural,
200
+ # ?automaton_type: :spa,
201
+ # ?params: Hash[Symbol, untyped],
202
+ # ?random: Random
203
+ # ) { (Array[In | Call | Return]) -> bool } -> Automaton::SPA[In, Call, Return]
204
+ def self.learn: [In] (alphabet: Array[In], sul: Automaton::DFA[In] | System::MooreLikeSUL[In, bool], ?oracle: oracle_type | Equiv::Oracle[In, bool], ?oracle_params: Hash[Symbol, untyped], ?algorithm: algorithm_name, ?automaton_type: :dfa, ?params: Hash[Symbol, untyped], ?random: Random) -> Automaton::DFA[In]
205
+ | [In] (alphabet: Array[In], ?oracle: oracle_type | Equiv::Oracle[In, bool], ?oracle_params: Hash[Symbol, untyped], ?algorithm: algorithm_name, ?automaton_type: :dfa, ?params: Hash[Symbol, untyped], ?random: Random) { (Array[In]) -> bool } -> Automaton::DFA[In]
206
+ | [In, Out] (alphabet: Array[In], sul: Automaton::Mealy[In, Out] | System::SUL[In, Out], automaton_type: :mealy, ?oracle: oracle_type | Equiv::Oracle[In, Out], ?oracle_params: Hash[Symbol, untyped], ?algorithm: algorithm_name, ?params: Hash[Symbol, untyped], ?random: Random) -> Automaton::Mealy[In, Out]
207
+ | [In, Out] (alphabet: Array[In], automaton_type: :mealy, ?oracle: oracle_type | Equiv::Oracle[In, Out], ?oracle_params: Hash[Symbol, untyped], ?algorithm: algorithm_name, ?params: Hash[Symbol, untyped], ?random: Random) { (Array[In]) -> Out } -> Automaton::Mealy[In, Out]
208
+ | [In, Out] (alphabet: Array[In], sul: Automaton::Moore[In, Out] | System::MooreLikeSUL[In, Out], automaton_type: :moore, ?oracle: oracle_type | Equiv::Oracle[In, Out], ?oracle_params: Hash[Symbol, untyped], ?algorithm: algorithm_name, ?params: Hash[Symbol, untyped], ?random: Random) -> Automaton::Moore[In, Out]
209
+ | [In, Out] (alphabet: Array[In], automaton_type: :moore, ?oracle: oracle_type | Equiv::Oracle[In, Out], ?oracle_params: Hash[Symbol, untyped], ?algorithm: algorithm_name, ?params: Hash[Symbol, untyped], ?random: Random) { (Array[In]) -> Out } -> Automaton::Moore[In, Out]
210
+ | [In, Call, Return] (alphabet: Array[In], call_alphabet: Array[Call], return_alphabet: Array[Return], sul: Automaton::VPA[In, Call, Return] | System::MooreLikeSUL[In | Call | Return, bool], ?oracle: oracle_type | Equiv::Oracle[In | Call | Return, bool], ?oracle_params: Hash[Symbol, untyped], ?algorithm: :kearns_vazirani_vpa, ?automaton_type: :vpa, ?params: Hash[Symbol, untyped], ?random: Random) -> Automaton::VPA[In, Call, Return]
211
+ | [In, Call, Return] (alphabet: Array[In], call_alphabet: Array[Call], return_alphabet: Array[Return], ?oracle: oracle_type | Equiv::Oracle[In | Call | Return, bool], ?oracle_params: Hash[Symbol, untyped], ?algorithm: :kearns_vazirani_vpa, ?automaton_type: :vpa, ?params: Hash[Symbol, untyped], ?random: Random) { (Array[In | Call | Return]) -> bool } -> Automaton::VPA[In, Call, Return]
212
+ | [In, Call, Return] (alphabet: Array[In], call_alphabet: Array[Call], return_input: Return, sul: Automaton::SPA[In, Call, Return] | System::MooreLikeSUL[In | Call | Return, bool], ?oracle: oracle_type | Equiv::Oracle[In | Call | Return, bool], ?oracle_params: Hash[Symbol, untyped], ?algorithm: :procedural, ?automaton_type: :spa, ?params: Hash[Symbol, untyped], ?random: Random) -> Automaton::SPA[In, Call, Return]
213
+ | [In, Call, Return] (alphabet: Array[In], call_alphabet: Array[Call], return_input: Return, ?oracle: oracle_type | Equiv::Oracle[In | Call | Return, bool], ?oracle_params: Hash[Symbol, untyped], ?algorithm: :procedural, ?automaton_type: :spa, ?params: Hash[Symbol, untyped], ?random: Random) { (Array[In | Call | Return]) -> bool } -> Automaton::SPA[In, Call, Return]
214
+ end
@@ -0,0 +1,14 @@
1
+ # Generated from test/example_test.rb with RBS::Inline
2
+
3
+ class ExampleTest < Minitest::Test
4
+ EXAMPLES_DIR: String
5
+
6
+ # : (*String cmd) -> String
7
+ def capture: (*String cmd) -> String
8
+
9
+ # : () -> void
10
+ def test_text_example_uri_parse_regexp: () -> void
11
+
12
+ # : () -> void
13
+ def test_text_example_ripper_prism: () -> void
14
+ end
@@ -0,0 +1,16 @@
1
+ # Generated from test/lernen/algorithm/kearns_vazirani_test.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ module Algorithm
5
+ class KearnsVaziraniTest < Minitest::Test
6
+ # : () -> void
7
+ def test_learn_dfa: () -> void
8
+
9
+ # : () -> void
10
+ def test_learn_moore: () -> void
11
+
12
+ # : () -> void
13
+ def test_learn_mealy: () -> void
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ # Generated from test/lernen/algorithm/kearns_vazirani_vpa_test.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ module Algorithm
5
+ class KearnsVaziraniVPATest < Minitest::Test
6
+ # : () -> void
7
+ def test_learn: () -> void
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ # Generated from test/lernen/algorithm/lsharp_test.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ module Algorithm
5
+ class LSharpTest < Minitest::Test
6
+ # : () -> void
7
+ def test_learn_dfa: () -> void
8
+
9
+ # : () -> void
10
+ def test_learn_moore: () -> void
11
+
12
+ # : () -> void
13
+ def test_learn_mealy: () -> void
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # Generated from test/lernen/algorithm/lstar_test.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ module Algorithm
5
+ class LStarTest < Minitest::Test
6
+ # : () -> void
7
+ def test_learn_dfa: () -> void
8
+
9
+ # : () -> void
10
+ def test_learn_moore: () -> void
11
+
12
+ # : () -> void
13
+ def test_learn_mealy: () -> void
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ # Generated from test/lernen/algorithm/procedural_test.rb with RBS::Inline
2
+
3
+ module Lernen
4
+ module Algorithm
5
+ class ProceduralTest < Minitest::Test
6
+ # : () -> void
7
+ def test_learn: () -> void
8
+ end
9
+ end
10
+ end