nfa2dfa 1.0.2 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3c062458afee68eb899ec35c6fee8e82ea0366cb
4
- data.tar.gz: 9f5191740fba0e5b0b865cd9d3e3b1af3a22856e
3
+ metadata.gz: 0dd869aacabd6004faccc4de1a7f9b35f7ec8b3c
4
+ data.tar.gz: dfe9e1cb14760e786a2b4ea5b0de62620c53e2ba
5
5
  SHA512:
6
- metadata.gz: a4c92af38dc76982b669a26d3ba61b3038fd5f28496f37f4d1f7f6ecaf26565365fdf71e4f42da9e27062501ffe582f98348f9feb58764a0a31e4665f9aa786c
7
- data.tar.gz: 2f1c55ad5e1a8efd8d3ff31bc7b060a063698d30d32ba370fe34d85a796b16df8ef49c940b4438cf0a86c4198aa5e645fc0911a7ad17fd655b940ec78d43c573
6
+ metadata.gz: ecb4a5153853a308678183c024a342d59c1f5a8272398bc03243351656322322959c3acabcdf840c19f62feafb9ec63a74ab087cf881790c222d194364dae20e
7
+ data.tar.gz: bc6bfa2a48abeac27a93521dfe5184a8ff4f1e7a07a407d5ba019027099acf5195e786d6604e9ab9cde6fab834f64b6112244c80259b8e336a65f55261a85feb
data/bin/automaton ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'commander/import'
5
+ require 'nfa2dfa'
6
+ program :version, '0.0.1'
7
+ program :description, 'Controller of automaton'
8
+ program :name, 'automaton'
9
+
10
+ command :create_finite do |c|
11
+ c.syntax = 'automaton create_finite [options]'
12
+ c.description = 'Creates determined automaton from file and writes it into "<input_file>.determined"'
13
+ c.action do |args|
14
+ args.each do |arg|
15
+ input_mat = Nfa2Dfa::Automaton.init(arg)
16
+ output_mat = input_mat.determine
17
+ data = output_mat.to_str
18
+ File.open(arg + ".determined", 'w') { |file| file.write(data) }
19
+ end
20
+ end
21
+ end
22
+
23
+ command :automaton_to_png do |c|
24
+ c.syntax = 'automaton automaton_to_png [options]'
25
+ c.description = 'Creates png representation of automaton from input'
26
+ c.action do |args|
27
+ args.each do |arg|
28
+ input_mat = Nfa2Dfa::Automaton.init(arg)
29
+ data = input_mat.to_graph(arg + ".png")
30
+ end
31
+ end
32
+ end
33
+
data/lib/nfa2dfa.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  module Nfa2Dfa
3
2
  require_relative 'automaton'
4
3
  require_relative 'state'
@@ -0,0 +1,134 @@
1
+ require 'rspec'
2
+ require 'spec_helper'
3
+ require_relative '../lib/automaton.rb'
4
+
5
+ describe Nfa2Dfa::Automaton do
6
+ before(:each) do
7
+ @file_path = "#{File.dirname(__FILE__)}/testdata/valid_input.automat"
8
+ @file_path2 = "#{File.dirname(__FILE__)}/testdata/valid_input2.automat"
9
+ @file_path3 = "#{File.dirname(__FILE__)}/testdata/valid_input3.automat"
10
+ end
11
+ context "initializes as" do
12
+ it "valid automaton" do
13
+ mat = Automaton.init(@file_path)
14
+ mat.should_not eq NIL
15
+ mat.class.should eq Nfa2Dfa::Automaton
16
+ end
17
+ it "invalid automaton, when there is invalid input" do
18
+ mat = Automaton.init("#{File.dirname(__FILE__)}/testdata/invalid_input.automat")
19
+ mat.should eq NIL
20
+ end
21
+ end
22
+ it "should be exportable in same format by method 'to_str'" do
23
+ valid_str = "z f\na b\nz-a-f f-b-f\nz\nf"
24
+ mat = Automaton.init(@file_path)
25
+ mat.to_str.should eq valid_str
26
+ end
27
+
28
+ context "accepts method resolves" do
29
+ subject { Automaton.init(@file_path) }
30
+ it "valid words" do
31
+ (subject.accepts? "a b").should eq true
32
+ (subject.accepts? "a").should eq true
33
+ (subject.accepts? "a b b b").should eq true
34
+ (subject.accepts? "a b b").should eq true
35
+ end
36
+
37
+ it "invalid words" do
38
+ (subject.accepts? "").should eq false
39
+ (subject.accepts? "a a").should eq false
40
+ (subject.accepts? "a a ").should eq false
41
+ (subject.accepts? "a b a").should eq false
42
+ end
43
+ end
44
+
45
+ it "should be able to check if automat is deterministic" do
46
+ Automaton.init(@file_path).deterministic?.should eq true
47
+ Automaton.init(@file_path2).deterministic?.should eq false
48
+ end
49
+
50
+ context "can create deterministic automaton" do
51
+ it "returns Automaton class" do
52
+ mat1 = Automaton.init(@file_path)
53
+ mat2 = Automaton.init(@file_path2)
54
+ mat3 = Automaton.init(@file_path3)
55
+ mat1.determine.class.should eq Nfa2Dfa::Automaton
56
+ mat2.determine.class.should eq Nfa2Dfa::Automaton
57
+ mat3.determine.class.should eq Nfa2Dfa::Automaton
58
+ end
59
+ it "returns same instance of Automaton when already deterministic" do
60
+ mat1 = Automaton.init(@file_path)
61
+ mat1det = mat1.determine
62
+ mat1.should eq mat1det
63
+ end
64
+ it "returns deterministic automaton" do
65
+ mat2 = Automaton.init(@file_path2)
66
+ mat2det = mat2.determine
67
+ mat2det.deterministic?.should eq true
68
+ end
69
+
70
+ it "which can accept same words" do
71
+ mat2 = Automaton.init(@file_path2)
72
+ mat2det = mat2.determine
73
+ word = ""
74
+ (mat2.accepts? word).should eq mat2det.accepts? word
75
+ (mat2.accepts? word).should eq true
76
+ word = "a a"
77
+ (mat2.accepts? word).should eq mat2det.accepts? word
78
+ (mat2.accepts? word).should eq true
79
+ word = "a b"
80
+ (mat2.accepts? word).should eq mat2det.accepts? word
81
+ (mat2.accepts? word).should eq true
82
+ word = "a c"
83
+ (mat2.accepts? word).should eq mat2det.accepts? word
84
+ (mat2.accepts? word).should eq true
85
+ word = "a c c"
86
+ (mat2.accepts? word).should eq mat2det.accepts? word
87
+ (mat2.accepts? word).should eq true
88
+ word = "a c c a"
89
+ (mat2.accepts? word).should eq mat2det.accepts? word
90
+ (mat2.accepts? word).should eq true
91
+ word = "a c c a c a"
92
+ (mat2.accepts? word).should eq mat2det.accepts? word
93
+ (mat2.accepts? word).should eq true
94
+ word = "a c c a c a a b"
95
+ (mat2.accepts? word).should eq mat2det.accepts? word
96
+ (mat2.accepts? word).should eq true
97
+ word = "c a b c a b c"
98
+ (mat2.accepts? word).should eq mat2det.accepts? word
99
+ (mat2.accepts? word).should eq true
100
+ word = "a c c b c"
101
+ (mat2.accepts? word).should eq mat2det.accepts? word
102
+ (mat2.accepts? word).should eq true
103
+ end
104
+
105
+ it "which rejects same words" do
106
+ mat2 = Automaton.init(@file_path3)
107
+ mat2det = mat2.determine
108
+ word = "0"
109
+ (mat2.accepts? word).should eq mat2det.accepts? word
110
+ (mat2.accepts? word).should eq false
111
+ word = "1"
112
+ (mat2.accepts? word).should eq mat2det.accepts? word
113
+ (mat2.accepts? word).should eq false
114
+ word = "0 1"
115
+ (mat2.accepts? word).should eq mat2det.accepts? word
116
+ (mat2.accepts? word).should eq false
117
+ word = "1 0"
118
+ (mat2.accepts? word).should eq mat2det.accepts? word
119
+ (mat2.accepts? word).should eq false
120
+ word = "1 1 1 1 0"
121
+ (mat2.accepts? word).should eq mat2det.accepts? word
122
+ (mat2.accepts? word).should eq false
123
+ word = "0 0 0 0 1"
124
+ (mat2.accepts? word).should eq mat2det.accepts? word
125
+ (mat2.accepts? word).should eq false
126
+ end
127
+
128
+ it "should have method for exporting as GraphViz 'to_graph'" do
129
+ mat = Automaton.init(@file_path2)
130
+ expect(mat.methods.include?(:to_graph)).to be true
131
+ end
132
+ end
133
+ end
134
+
@@ -0,0 +1,101 @@
1
+ require 'rspec'
2
+ require 'spec_helper'
3
+ require_relative '../lib/state.rb'
4
+
5
+ describe Nfa2Dfa::State do
6
+ before(:each) do
7
+ @end_state = State.new("end")
8
+ @end_state.to_starting_node
9
+ end
10
+ context "should keep " do
11
+ subject { State.new("state") }
12
+
13
+ it "basic data" do
14
+ subject.id.should eq "state"
15
+ subject.is_final.should eq false
16
+ end
17
+
18
+ it "transitions as private data" do
19
+ expect { subject.transitions }.to raise_error NoMethodError
20
+ end
21
+
22
+ it "added transitions" do
23
+ trans = Transition.new(subject, "jump", @end_state)
24
+ transes = subject.add_transition(trans)
25
+ transes.size.should eq 1
26
+ transes[0].should eq trans
27
+ end
28
+
29
+ it "cleared transition array" do
30
+ subject.clear_transitions.size.should eq 0
31
+ end
32
+ end
33
+
34
+ it "should be able to be finalized" do
35
+ state_a = State.new("a")
36
+ state_a.is_final.should eq false
37
+ state_a.finalize
38
+ state_a.is_final.should eq true
39
+ state_a.finalize
40
+ state_a.is_final.should eq true
41
+ end
42
+ it "should be able to be starting node" do
43
+ state_a = State.new("a")
44
+ state_a.is_starting.should eq false
45
+ state_a.to_starting_node
46
+ state_a.is_starting.should eq true
47
+ state_a.to_starting_node
48
+ state_a.is_starting.should eq true
49
+ end
50
+
51
+ context "gets correct next state" do
52
+ trans = []
53
+ state_a = State.new("a")
54
+ state_b = State.new("b")
55
+ state_c = State.new("c")
56
+ trans[0] = Transition.new(state_a, "0", state_b)
57
+ trans[1] = Transition.new(state_b, "1", state_a)
58
+ trans[2] = Transition.new(state_a, "0", state_a)
59
+ trans[3] = Transition.new(state_c, "1", state_a)
60
+ trans[4] = Transition.new(state_a, "0", state_c)
61
+ state_a.add_transition(trans[0])
62
+ state_a.add_transition(trans[2])
63
+ state_a.add_transition(trans[4])
64
+ state_b.add_transition(trans[1])
65
+ state_c.add_transition(trans[3])
66
+
67
+ it "array" do
68
+ state_a.get_next("0").size.should eq 3
69
+ state_a.get_next("1").size.should eq 0
70
+ end
71
+
72
+ it "in first step" do
73
+ state_a.get_next("0")[0].should eq state_b
74
+ end
75
+
76
+ it "in second step" do
77
+ state_a.get_next("0")[0].get_next("1")[0].should eq state_a
78
+ end
79
+ end
80
+
81
+ context "while conversion from NFA to DFA" do
82
+ trans = Array.new
83
+ state_a = State.new("a")
84
+ state_b = State.new("b")
85
+ state_c = State.new("c")
86
+ trans[0] = Transition.new(state_a, "0", state_b)
87
+ trans[1] = Transition.new(state_b, "1", state_a)
88
+ trans[2] = Transition.new(state_a, "0", state_a)
89
+ trans[3] = Transition.new(state_c, "1", state_a)
90
+ trans[4] = Transition.new(state_a, "0", state_c)
91
+
92
+ subject { State.new("a,b") }
93
+ it "should find correct transitions" do
94
+ subject.associate_transitions(trans)
95
+ subject.get_next("a").size.should eq 0
96
+ subject.get_next("1").size.should eq 1
97
+ subject.get_next("0").size.should eq 3
98
+ end
99
+ end
100
+ end
101
+
@@ -0,0 +1,28 @@
1
+ require 'rspec'
2
+ require 'spec_helper'
3
+ require_relative '../lib/transition.rb'
4
+
5
+ describe Nfa2Dfa::Transition do
6
+ context "should keep " do
7
+ state1 = State.new("1")
8
+ state2 = State.new("2")
9
+ state2.finalize
10
+ subject { Transition.new(state1, "a", state2) }
11
+
12
+ it "states" do
13
+ subject.beginning_state.should eq state1
14
+ subject.ending_state.should eq state2
15
+ end
16
+
17
+ it "transition alphabet" do
18
+ subject.alphabet.should eq "a"
19
+ end
20
+
21
+ it "correct types" do
22
+ subject.beginning_state.class.should eq State
23
+ subject.ending_state.class.should eq State
24
+ subject.alphabet.class.should eq String
25
+ end
26
+ end
27
+ end
28
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nfa2dfa
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Zachov
@@ -12,7 +12,8 @@ date: 2013-10-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Finite automaton determinizer
14
14
  email: martin.zachov@gmail.com
15
- executables: []
15
+ executables:
16
+ - automaton
16
17
  extensions: []
17
18
  extra_rdoc_files: []
18
19
  files:
@@ -20,6 +21,10 @@ files:
20
21
  - lib/automaton.rb
21
22
  - lib/transition.rb
22
23
  - lib/nfa2dfa.rb
24
+ - spec/automaton_spec.rb
25
+ - spec/state_spec.rb
26
+ - spec/transition_spec.rb
27
+ - bin/automaton
23
28
  homepage: http://fit.cvut.cz
24
29
  licenses:
25
30
  - GNU GPL
@@ -44,4 +49,7 @@ rubygems_version: 2.0.3
44
49
  signing_key:
45
50
  specification_version: 4
46
51
  summary: MI-RUB semestral
47
- test_files: []
52
+ test_files:
53
+ - spec/automaton_spec.rb
54
+ - spec/state_spec.rb
55
+ - spec/transition_spec.rb