cellula 0.1.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.
- checksums.yaml +7 -0
- data/Changelog.markdown +27 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +48 -0
- data/LICENSE +167 -0
- data/README.markdown +97 -0
- data/Rakefile +30 -0
- data/TODO +9 -0
- data/VERSION +1 -0
- data/bin/cellula +40 -0
- data/lib/cellula.rb +77 -0
- data/lib/cellula/automaton.rb +125 -0
- data/lib/cellula/automaton_builder.rb +55 -0
- data/lib/cellula/rule.rb +2 -0
- data/lib/cellula/rules/rule.rb +30 -0
- data/lib/cellula/rules/wolfram_code_rule.rb +145 -0
- data/lib/cellula/study.rb +76 -0
- data/lib/cellula/study_builder.rb +43 -0
- metadata +148 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: de9f62a45eba74c614a88bc2d734061d3003678f
|
|
4
|
+
data.tar.gz: d75b7307f6fd8e33831b31eb5a0a5d754f40316c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c3aa5d7269e076dcb6ce23f4a5b72632258791152d432bd629b03e60bfece1b2239f3956736195bcf874c7ac8ac6821b96112f48221ef0a2f41db17e65b9b5e9
|
|
7
|
+
data.tar.gz: 39d31eed7ea97587959afaf8265fa9b9e59de9fba7b733be2f4fb2dcc85458624b1bbc7320f967584cc41b14ae87cc292603a7ea80061dfd4683309abbb863a9
|
data/Changelog.markdown
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
This changelog is auto-generated using git-changelog.
|
|
2
|
+
See https://github.com/lkdjiin/git-changelog for more information.
|
|
3
|
+
|
|
4
|
+
* 2013-08-06 Generate dev's documentation
|
|
5
|
+
* 2013-08-06 Improve readme
|
|
6
|
+
* 2013-08-06 Improve documentation
|
|
7
|
+
* 2013-08-06 Fix bug in single 1 histories method
|
|
8
|
+
* 2013-08-06 Apache License v2
|
|
9
|
+
* 2013-08-06 Add tests for single 1 histories study method
|
|
10
|
+
Those tests fail for now.
|
|
11
|
+
* 2013-08-04 Add a test for :single study's method
|
|
12
|
+
* 2013-08-04 Add single 1 study method for elementary CA
|
|
13
|
+
This seems to be buggy. It works well with certain wolfram codes and
|
|
14
|
+
not so well with other ones. Problem is I don't really understand
|
|
15
|
+
how «single 1 histories» method of study works. I have to read more
|
|
16
|
+
on the subject.
|
|
17
|
+
* 2013-08-03 Refactoring
|
|
18
|
+
* 2013-08-03 Add reek to gemspec
|
|
19
|
+
* 2013-08-03 Extract WolframCodeRule from Rule
|
|
20
|
+
* 2013-08-03 Use Study instance
|
|
21
|
+
* 2013-08-03 Replace student by study in doc
|
|
22
|
+
* 2013-08-03 Rename Student to Study
|
|
23
|
+
* 2013-08-02 Print message and exit when bad cellula file
|
|
24
|
+
* 2013-08-02 Add basic Rule class
|
|
25
|
+
* 2013-08-02 Basic Automaton and Student objects
|
|
26
|
+
* 2013-08-01 Not anymore a library
|
|
27
|
+
* 2013-08-01 First commit
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
cellula (0.1.0)
|
|
5
|
+
docile (= 1.1.0)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
coco (0.7.1)
|
|
11
|
+
diff-lcs (1.2.4)
|
|
12
|
+
docile (1.1.0)
|
|
13
|
+
rake (10.1.0)
|
|
14
|
+
reek (1.3.1)
|
|
15
|
+
ruby2ruby (~> 2.0.2)
|
|
16
|
+
ruby_parser (~> 3.1.1)
|
|
17
|
+
sexp_processor
|
|
18
|
+
rspec (2.14.1)
|
|
19
|
+
rspec-core (~> 2.14.0)
|
|
20
|
+
rspec-expectations (~> 2.14.0)
|
|
21
|
+
rspec-mocks (~> 2.14.0)
|
|
22
|
+
rspec-core (2.14.4)
|
|
23
|
+
rspec-expectations (2.14.0)
|
|
24
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
|
25
|
+
rspec-mocks (2.14.2)
|
|
26
|
+
ruby2ruby (2.0.6)
|
|
27
|
+
ruby_parser (~> 3.1)
|
|
28
|
+
sexp_processor (~> 4.0)
|
|
29
|
+
ruby_parser (3.1.3)
|
|
30
|
+
sexp_processor (~> 4.1)
|
|
31
|
+
sexp_processor (4.2.1)
|
|
32
|
+
tomparse (0.4.2)
|
|
33
|
+
yard (0.8.7)
|
|
34
|
+
yard-tomdoc (0.7.1)
|
|
35
|
+
tomparse (>= 0.4.0)
|
|
36
|
+
yard
|
|
37
|
+
|
|
38
|
+
PLATFORMS
|
|
39
|
+
ruby
|
|
40
|
+
|
|
41
|
+
DEPENDENCIES
|
|
42
|
+
cellula!
|
|
43
|
+
coco (>= 0.7.1)
|
|
44
|
+
rake
|
|
45
|
+
reek
|
|
46
|
+
rspec
|
|
47
|
+
yard
|
|
48
|
+
yard-tomdoc
|
data/LICENSE
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction, and
|
|
10
|
+
distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
|
13
|
+
owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all other entities
|
|
16
|
+
that control, are controlled by, or are under common control with that entity.
|
|
17
|
+
For the purposes of this definition, "control" means (i) the power, direct or
|
|
18
|
+
indirect, to cause the direction or management of such entity, whether by
|
|
19
|
+
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
20
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
21
|
+
|
|
22
|
+
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
|
23
|
+
permissions granted by this License.
|
|
24
|
+
|
|
25
|
+
"Source" form shall mean the preferred form for making modifications, including
|
|
26
|
+
but not limited to software source code, documentation source, and configuration
|
|
27
|
+
files.
|
|
28
|
+
|
|
29
|
+
"Object" form shall mean any form resulting from mechanical transformation or
|
|
30
|
+
translation of a Source form, including but not limited to compiled object code,
|
|
31
|
+
generated documentation, and conversions to other media types.
|
|
32
|
+
|
|
33
|
+
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
|
34
|
+
available under the License, as indicated by a copyright notice that is included
|
|
35
|
+
in or attached to the work (an example is provided in the Appendix below).
|
|
36
|
+
|
|
37
|
+
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
|
38
|
+
is based on (or derived from) the Work and for which the editorial revisions,
|
|
39
|
+
annotations, elaborations, or other modifications represent, as a whole, an
|
|
40
|
+
original work of authorship. For the purposes of this License, Derivative Works
|
|
41
|
+
shall not include works that remain separable from, or merely link (or bind by
|
|
42
|
+
name) to the interfaces of, the Work and Derivative Works thereof.
|
|
43
|
+
|
|
44
|
+
"Contribution" shall mean any work of authorship, including the original version
|
|
45
|
+
of the Work and any modifications or additions to that Work or Derivative Works
|
|
46
|
+
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
|
47
|
+
by the copyright owner or by an individual or Legal Entity authorized to submit
|
|
48
|
+
on behalf of the copyright owner. For the purposes of this definition,
|
|
49
|
+
"submitted" means any form of electronic, verbal, or written communication sent
|
|
50
|
+
to the Licensor or its representatives, including but not limited to
|
|
51
|
+
communication on electronic mailing lists, source code control systems, and
|
|
52
|
+
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
|
53
|
+
the purpose of discussing and improving the Work, but excluding communication
|
|
54
|
+
that is conspicuously marked or otherwise designated in writing by the copyright
|
|
55
|
+
owner as "Not a Contribution."
|
|
56
|
+
|
|
57
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
|
58
|
+
of whom a Contribution has been received by Licensor and subsequently
|
|
59
|
+
incorporated within the Work.
|
|
60
|
+
|
|
61
|
+
2. Grant of Copyright License.
|
|
62
|
+
|
|
63
|
+
Subject to the terms and conditions of this License, each Contributor hereby
|
|
64
|
+
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
|
65
|
+
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
|
66
|
+
publicly display, publicly perform, sublicense, and distribute the Work and such
|
|
67
|
+
Derivative Works in Source or Object form.
|
|
68
|
+
|
|
69
|
+
3. Grant of Patent License.
|
|
70
|
+
|
|
71
|
+
Subject to the terms and conditions of this License, each Contributor hereby
|
|
72
|
+
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
|
73
|
+
irrevocable (except as stated in this section) patent license to make, have
|
|
74
|
+
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
|
75
|
+
such license applies only to those patent claims licensable by such Contributor
|
|
76
|
+
that are necessarily infringed by their Contribution(s) alone or by combination
|
|
77
|
+
of their Contribution(s) with the Work to which such Contribution(s) was
|
|
78
|
+
submitted. If You institute patent litigation against any entity (including a
|
|
79
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
|
80
|
+
Contribution incorporated within the Work constitutes direct or contributory
|
|
81
|
+
patent infringement, then any patent licenses granted to You under this License
|
|
82
|
+
for that Work shall terminate as of the date such litigation is filed.
|
|
83
|
+
|
|
84
|
+
4. Redistribution.
|
|
85
|
+
|
|
86
|
+
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
|
87
|
+
in any medium, with or without modifications, and in Source or Object form,
|
|
88
|
+
provided that You meet the following conditions:
|
|
89
|
+
|
|
90
|
+
You must give any other recipients of the Work or Derivative Works a copy of
|
|
91
|
+
this License; and
|
|
92
|
+
You must cause any modified files to carry prominent notices stating that You
|
|
93
|
+
changed the files; and
|
|
94
|
+
You must retain, in the Source form of any Derivative Works that You distribute,
|
|
95
|
+
all copyright, patent, trademark, and attribution notices from the Source form
|
|
96
|
+
of the Work, excluding those notices that do not pertain to any part of the
|
|
97
|
+
Derivative Works; and
|
|
98
|
+
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
|
99
|
+
Derivative Works that You distribute must include a readable copy of the
|
|
100
|
+
attribution notices contained within such NOTICE file, excluding those notices
|
|
101
|
+
that do not pertain to any part of the Derivative Works, in at least one of the
|
|
102
|
+
following places: within a NOTICE text file distributed as part of the
|
|
103
|
+
Derivative Works; within the Source form or documentation, if provided along
|
|
104
|
+
with the Derivative Works; or, within a display generated by the Derivative
|
|
105
|
+
Works, if and wherever such third-party notices normally appear. The contents of
|
|
106
|
+
the NOTICE file are for informational purposes only and do not modify the
|
|
107
|
+
License. You may add Your own attribution notices within Derivative Works that
|
|
108
|
+
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
|
109
|
+
provided that such additional attribution notices cannot be construed as
|
|
110
|
+
modifying the License.
|
|
111
|
+
You may add Your own copyright statement to Your modifications and may provide
|
|
112
|
+
additional or different license terms and conditions for use, reproduction, or
|
|
113
|
+
distribution of Your modifications, or for any such Derivative Works as a whole,
|
|
114
|
+
provided Your use, reproduction, and distribution of the Work otherwise complies
|
|
115
|
+
with the conditions stated in this License.
|
|
116
|
+
|
|
117
|
+
5. Submission of Contributions.
|
|
118
|
+
|
|
119
|
+
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
|
120
|
+
for inclusion in the Work by You to the Licensor shall be under the terms and
|
|
121
|
+
conditions of this License, without any additional terms or conditions.
|
|
122
|
+
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
|
123
|
+
any separate license agreement you may have executed with Licensor regarding
|
|
124
|
+
such Contributions.
|
|
125
|
+
|
|
126
|
+
6. Trademarks.
|
|
127
|
+
|
|
128
|
+
This License does not grant permission to use the trade names, trademarks,
|
|
129
|
+
service marks, or product names of the Licensor, except as required for
|
|
130
|
+
reasonable and customary use in describing the origin of the Work and
|
|
131
|
+
reproducing the content of the NOTICE file.
|
|
132
|
+
|
|
133
|
+
7. Disclaimer of Warranty.
|
|
134
|
+
|
|
135
|
+
Unless required by applicable law or agreed to in writing, Licensor provides the
|
|
136
|
+
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
137
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
|
138
|
+
including, without limitation, any warranties or conditions of TITLE,
|
|
139
|
+
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
|
140
|
+
solely responsible for determining the appropriateness of using or
|
|
141
|
+
redistributing the Work and assume any risks associated with Your exercise of
|
|
142
|
+
permissions under this License.
|
|
143
|
+
|
|
144
|
+
8. Limitation of Liability.
|
|
145
|
+
|
|
146
|
+
In no event and under no legal theory, whether in tort (including negligence),
|
|
147
|
+
contract, or otherwise, unless required by applicable law (such as deliberate
|
|
148
|
+
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
|
149
|
+
liable to You for damages, including any direct, indirect, special, incidental,
|
|
150
|
+
or consequential damages of any character arising as a result of this License or
|
|
151
|
+
out of the use or inability to use the Work (including but not limited to
|
|
152
|
+
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
|
153
|
+
any and all other commercial damages or losses), even if such Contributor has
|
|
154
|
+
been advised of the possibility of such damages.
|
|
155
|
+
|
|
156
|
+
9. Accepting Warranty or Additional Liability.
|
|
157
|
+
|
|
158
|
+
While redistributing the Work or Derivative Works thereof, You may choose to
|
|
159
|
+
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
|
160
|
+
other liability obligations and/or rights consistent with this License. However,
|
|
161
|
+
in accepting such obligations, You may act only on Your own behalf and on Your
|
|
162
|
+
sole responsibility, not on behalf of any other Contributor, and only if You
|
|
163
|
+
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
|
164
|
+
incurred by, or claims asserted against, such Contributor by reason of your
|
|
165
|
+
accepting any such warranty or additional liability.
|
|
166
|
+
|
|
167
|
+
END OF TERMS AND CONDITIONS
|
data/README.markdown
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Cellula
|
|
2
|
+
================
|
|
3
|
+
|
|
4
|
+
Description
|
|
5
|
+
-----------
|
|
6
|
+
|
|
7
|
+
Cellula aims to be a framework for building, running and studying
|
|
8
|
+
cellular automata.
|
|
9
|
+
|
|
10
|
+
My main goal with Cellula is to *study* cellular automata, not only to *run*
|
|
11
|
+
them, so don't expect fancy graphics.
|
|
12
|
+
|
|
13
|
+
Another goal is to provide a simple DSL, allowing non-programmers to use
|
|
14
|
+
Cellula. Following is an example of Cellula DSL:
|
|
15
|
+
|
|
16
|
+
``` ruby
|
|
17
|
+
automaton "Test CA" do
|
|
18
|
+
dimensions 1
|
|
19
|
+
type :elementary
|
|
20
|
+
width 20
|
|
21
|
+
rule :wolfram_code_110
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
study "Test CA" do
|
|
25
|
+
method :random
|
|
26
|
+
generations 4
|
|
27
|
+
end
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Save the previous example in a file named `my_automaton.rb` and
|
|
31
|
+
launch it with:
|
|
32
|
+
|
|
33
|
+
cellula path/to/my_automaton.rb
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
Install
|
|
37
|
+
-------------------------
|
|
38
|
+
|
|
39
|
+
gem install cellula
|
|
40
|
+
|
|
41
|
+
Usage
|
|
42
|
+
--------------------------
|
|
43
|
+
*This is a work in progress. More documentation is coming…*
|
|
44
|
+
|
|
45
|
+
### automaton specifications
|
|
46
|
+
|
|
47
|
+
* dimensions
|
|
48
|
+
Number of dimensions of the grid. Currently Cellula supports only
|
|
49
|
+
1D grids.
|
|
50
|
+
* type
|
|
51
|
+
Type of the automaton. Currently only :elementary (one-dimensional, 2
|
|
52
|
+
possible states per cell, neighbors are the immediate neighbors' cells.
|
|
53
|
+
* width
|
|
54
|
+
Width of the grid.
|
|
55
|
+
* rule
|
|
56
|
+
Currently only Wolfram code.
|
|
57
|
+
|
|
58
|
+
### study specifications
|
|
59
|
+
|
|
60
|
+
* method
|
|
61
|
+
The study's method. Could be :random or :single. (View doc/study.rb
|
|
62
|
+
for more details)
|
|
63
|
+
* generations
|
|
64
|
+
Number of generations to process.
|
|
65
|
+
|
|
66
|
+
Dependencies
|
|
67
|
+
--------------------------
|
|
68
|
+
|
|
69
|
+
* ruby >= 2.0.0
|
|
70
|
+
|
|
71
|
+
Contributing
|
|
72
|
+
-------------------------
|
|
73
|
+
|
|
74
|
+
1. Fork it
|
|
75
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
76
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
77
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
78
|
+
5. Create new Pull Request
|
|
79
|
+
|
|
80
|
+
### There is many other ways to contibute to Cellula
|
|
81
|
+
|
|
82
|
+
1. Report any bugs
|
|
83
|
+
2. Give me ideas
|
|
84
|
+
3. Correct my poor english syntax
|
|
85
|
+
4. Blog about Cellula
|
|
86
|
+
5. Tell Cellula to your friends and colleagues
|
|
87
|
+
|
|
88
|
+
License
|
|
89
|
+
--------------------------
|
|
90
|
+
Apache v2 License (See LICENSE file).
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
Questions and/or Comments
|
|
94
|
+
--------------------------
|
|
95
|
+
|
|
96
|
+
Feel free to email [Xavier Nayrac](mailto:xavier.nayrac@gmail.com)
|
|
97
|
+
with any questions, or contact me on [twitter](https://twitter.com/lkdjiin).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
require 'rake'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
|
+
|
|
6
|
+
desc 'Test CellulaCore'
|
|
7
|
+
task :default => :spec
|
|
8
|
+
|
|
9
|
+
desc 'Test CellulaCore with rspec'
|
|
10
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
|
11
|
+
t.rspec_opts = ['--color']
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
desc 'Check for code smells'
|
|
15
|
+
task :reek do
|
|
16
|
+
puts 'Checking for code smells...'
|
|
17
|
+
files = Dir.glob 'lib/**/*.rb'
|
|
18
|
+
args = files.join(' ')
|
|
19
|
+
sh "reek --quiet #{args} | ./reek.sed"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
desc 'Generate documentation'
|
|
23
|
+
task :doc do
|
|
24
|
+
sh "yard --plugin tomdoc"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
desc "Generate the changelog"
|
|
28
|
+
task :changelog do
|
|
29
|
+
system "git changelog > Changelog.markdown"
|
|
30
|
+
end
|
data/TODO
ADDED
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
data/bin/cellula
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
|
4
|
+
$CELLULA_PATH = File.expand_path(File.dirname(__FILE__)) + '/..'
|
|
5
|
+
|
|
6
|
+
require 'cellula'
|
|
7
|
+
include Cellula
|
|
8
|
+
|
|
9
|
+
banner
|
|
10
|
+
|
|
11
|
+
if ARGV[0].nil?
|
|
12
|
+
usage
|
|
13
|
+
exit
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
load ARGV[0].dup
|
|
17
|
+
puts @study.say_hello
|
|
18
|
+
puts
|
|
19
|
+
|
|
20
|
+
def to_single_1_histories(gen)
|
|
21
|
+
right_remove = (gen[1].size - (gen[0] * 2 + 1)) / 2
|
|
22
|
+
gen[1].pop(right_remove)
|
|
23
|
+
gen[1].join
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
generations = []
|
|
27
|
+
|
|
28
|
+
@auto.generate(@study) do |num, generation|
|
|
29
|
+
generations << [num, generation]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
generations.each do |gen|
|
|
33
|
+
printf "%4s: %s\n", gen[0], gen[1].join()
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if @study.method == :single
|
|
37
|
+
puts "Serie: " +
|
|
38
|
+
generations.map{|e| to_single_1_histories(e).to_i(2)}.join(', ')
|
|
39
|
+
end
|
|
40
|
+
|
data/lib/cellula.rb
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require 'docile'
|
|
2
|
+
require 'cellula/automaton'
|
|
3
|
+
require 'cellula/study'
|
|
4
|
+
require 'cellula/automaton_builder'
|
|
5
|
+
require 'cellula/study_builder'
|
|
6
|
+
require 'cellula/rule'
|
|
7
|
+
|
|
8
|
+
# Public: Cellula is a framework for building, running and studying
|
|
9
|
+
# cellular automata. For this, Cellula provides a simple DSL.
|
|
10
|
+
#
|
|
11
|
+
# Following is an example of Cellula DSL:
|
|
12
|
+
#
|
|
13
|
+
# automaton "his name" do
|
|
14
|
+
# dimension 1
|
|
15
|
+
# type :elementary
|
|
16
|
+
# width 20
|
|
17
|
+
# rule :wolfram_code_110
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
# Save the previous example in a file named `my_automaton.rb` and
|
|
21
|
+
# launch it with:
|
|
22
|
+
#
|
|
23
|
+
# cellula path/to/my_automaton.rb
|
|
24
|
+
module Cellula
|
|
25
|
+
|
|
26
|
+
# Internal: Part of the DSL API, this method builds a new Automaton
|
|
27
|
+
# object via AutomatonBuilder.
|
|
28
|
+
#
|
|
29
|
+
# name - String name of the automaton.
|
|
30
|
+
# block - A Ruby block to build the automaton.
|
|
31
|
+
#
|
|
32
|
+
# Returns nothing.
|
|
33
|
+
def automaton(name, &block)
|
|
34
|
+
@auto = Docile.dsl_eval(AutomatonBuilder.new(name), &block).build
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Internal: Part of the DSL API, this method builds a new Study
|
|
38
|
+
# object via StudyBuilder.
|
|
39
|
+
#
|
|
40
|
+
# name - String name of the automaton to study.
|
|
41
|
+
# block - A Ruby block to build the automaton.
|
|
42
|
+
#
|
|
43
|
+
# Returns nothing.
|
|
44
|
+
def study(name, &block)
|
|
45
|
+
@study = Docile.dsl_eval(StudyBuilder.new(name), &block).build
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Public: Display a banner on stdout.
|
|
49
|
+
#
|
|
50
|
+
# Returns nothing.
|
|
51
|
+
def banner
|
|
52
|
+
puts "Cellula version " + File.read('VERSION').strip
|
|
53
|
+
puts ""
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Public: Display application's usage on stdout.
|
|
57
|
+
#
|
|
58
|
+
# Returns nothing.
|
|
59
|
+
def usage
|
|
60
|
+
puts "
|
|
61
|
+
usage:
|
|
62
|
+
|
|
63
|
+
cellula path/to/automaton_file.rb
|
|
64
|
+
"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Public: Print an error message and exit with code 1.
|
|
68
|
+
#
|
|
69
|
+
# message - The String message to display to user before exiting.
|
|
70
|
+
#
|
|
71
|
+
# Returns nothing.
|
|
72
|
+
def panic(message = "Unknown error")
|
|
73
|
+
puts "** Panic **"
|
|
74
|
+
puts message
|
|
75
|
+
exit(1)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
module Cellula
|
|
2
|
+
|
|
3
|
+
# Public: This class provides all it's needed to run a cellular
|
|
4
|
+
# automaton.
|
|
5
|
+
#
|
|
6
|
+
# You rarely wants to initialize an Automaton directly. This is
|
|
7
|
+
# because Automaton's creation needs a lots of parameters. It is
|
|
8
|
+
# much more simpler to create Automata using AutomatonBuilder class.
|
|
9
|
+
#
|
|
10
|
+
# Dimensions
|
|
11
|
+
# ----------
|
|
12
|
+
# Currently only support 1D cellular automata.
|
|
13
|
+
#
|
|
14
|
+
# Type of automaton
|
|
15
|
+
# -----------------
|
|
16
|
+
# Currently only support elementary cellular automaton. Quoted from
|
|
17
|
+
# Wikipedia:
|
|
18
|
+
#
|
|
19
|
+
# an elementary cellular automaton is a one-dimensional cellular
|
|
20
|
+
# automaton where there are two possible states (labeled 0 and 1)
|
|
21
|
+
# and the rule to determine the state of a cell in the next generation
|
|
22
|
+
# depends only on the current state of the cell and its two immediate
|
|
23
|
+
# neighbors.
|
|
24
|
+
#
|
|
25
|
+
# See http://en.wikipedia.org/wiki/Elementary_cellular_automaton
|
|
26
|
+
# for more details.
|
|
27
|
+
#
|
|
28
|
+
# Rule
|
|
29
|
+
# ----
|
|
30
|
+
# Currently support only wolfram code rules.
|
|
31
|
+
#
|
|
32
|
+
# I hope to support custom rules and types soon.
|
|
33
|
+
class Automaton
|
|
34
|
+
|
|
35
|
+
# Public: Initialize a new Automaton.
|
|
36
|
+
#
|
|
37
|
+
# name - String name of the automaton.
|
|
38
|
+
# dimensions - Integer number of dimensions for the automaton's
|
|
39
|
+
# grid. Default is 1.
|
|
40
|
+
# type - Currently only :elementary.
|
|
41
|
+
# width - The Integer width of the automaton's grid.
|
|
42
|
+
# rule - Rule of the automaton. Currently rule is a Symbol
|
|
43
|
+
# following this pattern: :wolfram_code_X, where X is
|
|
44
|
+
# the rule number, from 0 to 255.
|
|
45
|
+
def initialize(name, dimensions, type, width, rule)
|
|
46
|
+
panic "Bad dimensions: #{dimensions}" if dimensions != 1
|
|
47
|
+
panic "Bad type: #{type}" if type != :elementary
|
|
48
|
+
panic "Bad width: #{width}" if width < 1
|
|
49
|
+
@name = name
|
|
50
|
+
@dimensions = dimensions
|
|
51
|
+
@type = type
|
|
52
|
+
@width = width
|
|
53
|
+
@rule = Rule.new(rule)
|
|
54
|
+
@grid = Array.new(@width)
|
|
55
|
+
@grid.map! {|item| rand(2) }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Public: Get the String name of the automaton.
|
|
59
|
+
attr_reader :name
|
|
60
|
+
|
|
61
|
+
# Public: Set/get the Integer dimensions of the automaton's grid.
|
|
62
|
+
attr_accessor :dimensions
|
|
63
|
+
|
|
64
|
+
# Public: Set/get the Symbol type of the automaton.
|
|
65
|
+
attr_accessor :type
|
|
66
|
+
|
|
67
|
+
# Public: Set/get the Integer width of the automaton's grid.
|
|
68
|
+
attr_accessor :width
|
|
69
|
+
|
|
70
|
+
# Public: Get the rule of the automaton.
|
|
71
|
+
attr_reader :rule
|
|
72
|
+
|
|
73
|
+
# Public: Generate successive generations of this automaton.
|
|
74
|
+
# If, for example, `student.generations == 4` then #generate will
|
|
75
|
+
# produce 5 generations: The original generation plus the four you
|
|
76
|
+
# want.
|
|
77
|
+
#
|
|
78
|
+
# study - Study instance.
|
|
79
|
+
# block - What to do with a generation.
|
|
80
|
+
#
|
|
81
|
+
# Example
|
|
82
|
+
#
|
|
83
|
+
# automaton.generate(study) do |num, generation|
|
|
84
|
+
# printf "Gen %4s: %s\n", num, generation.join()
|
|
85
|
+
# end
|
|
86
|
+
# # => will result in something like that:
|
|
87
|
+
# # => Gen 0: 0101001010001011000001000100000100101011
|
|
88
|
+
# # => Gen 1: 0000010000010000000010001000001001000000
|
|
89
|
+
# # => Gen 2: 0000100000100000000100010000010010000000
|
|
90
|
+
# # => Gen 3: 0001000001000000001000100000100100000000
|
|
91
|
+
# # => Gen 4: 0010000010000000010001000001001000000000
|
|
92
|
+
#
|
|
93
|
+
# Returns successive generations as Array.
|
|
94
|
+
def generate(study, &block)
|
|
95
|
+
adapt_for_single_method if study.method == :single
|
|
96
|
+
block.call(0, @grid)
|
|
97
|
+
1.upto(study.generations) do |cell_index|
|
|
98
|
+
apply_rule(study)
|
|
99
|
+
block.call(cell_index, @grid)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
# Returns nothing.
|
|
106
|
+
def adapt_for_single_method
|
|
107
|
+
@width += 1 if @width % 2 == 0
|
|
108
|
+
@grid = Array.new(@width, 0)
|
|
109
|
+
@grid[@width / 2] = 1
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Apply rule to the entire grid. @grid becomes the next generation.
|
|
113
|
+
#
|
|
114
|
+
# study - Study instance.
|
|
115
|
+
#
|
|
116
|
+
# Returns nothing.
|
|
117
|
+
def apply_rule(study)
|
|
118
|
+
next_grid = @grid.map.with_index do |cell, index|
|
|
119
|
+
@rule.apply_rule(index, @grid, study)
|
|
120
|
+
end
|
|
121
|
+
@grid = next_grid
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module Cellula
|
|
2
|
+
|
|
3
|
+
# Public: Provides an interface to build Automaton objects.
|
|
4
|
+
#
|
|
5
|
+
# Examples
|
|
6
|
+
#
|
|
7
|
+
# ca = AutomatonBuilder.new("my name").build
|
|
8
|
+
# ca = AutomatonBuilder.new("my name").dimensions(2).build
|
|
9
|
+
class AutomatonBuilder
|
|
10
|
+
|
|
11
|
+
# Public: Initialize an new AutomatonBuilder.
|
|
12
|
+
#
|
|
13
|
+
# name - String name of the futur Automaton.
|
|
14
|
+
def initialize(name)
|
|
15
|
+
@name = name
|
|
16
|
+
@dimensions = 1
|
|
17
|
+
@type = :elementary
|
|
18
|
+
@width = 20
|
|
19
|
+
@rule = :wolfram_code_110
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Public: Set the Integer dimensions of the automaton's grid.
|
|
23
|
+
# Default is 1.
|
|
24
|
+
#
|
|
25
|
+
# Returns self.
|
|
26
|
+
def dimensions(val); @dimensions = val; self; end
|
|
27
|
+
|
|
28
|
+
# Public: Set the Symbol type of the automaton. Default is
|
|
29
|
+
# :elementary.
|
|
30
|
+
#
|
|
31
|
+
# Returns self.
|
|
32
|
+
def type(val); @type = val; self; end
|
|
33
|
+
|
|
34
|
+
# Public: Set the Integer width of the automaton's grid.
|
|
35
|
+
# Default is 20.
|
|
36
|
+
#
|
|
37
|
+
# Returns self.
|
|
38
|
+
def width(val); @width = val; self; end
|
|
39
|
+
|
|
40
|
+
# Public: Set the rule of the automaton.
|
|
41
|
+
# Default is :wolfram_code_110.
|
|
42
|
+
#
|
|
43
|
+
# Returns self.
|
|
44
|
+
def rule(val); @rule = val; self; end
|
|
45
|
+
|
|
46
|
+
# Public: Builds an Automaton with characteristics given with
|
|
47
|
+
# the setters methods.
|
|
48
|
+
#
|
|
49
|
+
# Returns Automaton.
|
|
50
|
+
def build
|
|
51
|
+
Automaton.new(@name, @dimensions, @type, @width, @rule)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
data/lib/cellula/rule.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Cellula
|
|
2
|
+
|
|
3
|
+
# Internal: Know how to apply a rule to a single cell.
|
|
4
|
+
class Rule
|
|
5
|
+
|
|
6
|
+
# Public: Initialize a new Rule object.
|
|
7
|
+
#
|
|
8
|
+
# rule - Currently accept only wolfram code, in the form
|
|
9
|
+
# of a Symbol like :wolfram_code_110.
|
|
10
|
+
def initialize(rule)
|
|
11
|
+
if WolframCodeRule.wolfram_code?(rule)
|
|
12
|
+
@rule = WolframCodeRule.new WolframCodeRule.wolfram_code(rule)
|
|
13
|
+
else
|
|
14
|
+
panic "Unknown rule: #{rule.to_s}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Public: Apply the rule on a single cell.
|
|
19
|
+
#
|
|
20
|
+
# cell_number - Integer number of the cell to apply the rule on.
|
|
21
|
+
# grid - The entire grid as an Array of Integer.
|
|
22
|
+
# study - Study instance.
|
|
23
|
+
#
|
|
24
|
+
# Returns the Integer new state of the cell for the next generation.
|
|
25
|
+
def apply_rule(cell_number, grid, study)
|
|
26
|
+
@rule.apply_rule(cell_number, grid, study)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
module Cellula
|
|
2
|
+
|
|
3
|
+
# Internal: Know how to apply a Wolfram code rule on a single cell.
|
|
4
|
+
class WolframCodeRule
|
|
5
|
+
|
|
6
|
+
# Public: Initialize a new WolframCodeRule object.
|
|
7
|
+
# See http://en.wikipedia.org/wiki/Wolfram_code and
|
|
8
|
+
# http://en.wikipedia.org/wiki/Elementary_cellular_automaton
|
|
9
|
+
# for details.
|
|
10
|
+
#
|
|
11
|
+
# rule_number - Integer number of the wolfram code (a number between
|
|
12
|
+
# 0 and 255).
|
|
13
|
+
def initialize(rule_number)
|
|
14
|
+
@rule_number = rule_number
|
|
15
|
+
begin
|
|
16
|
+
check_rule_number
|
|
17
|
+
rescue Exception => ex
|
|
18
|
+
panic ex.message
|
|
19
|
+
end
|
|
20
|
+
@binary_string = "%08b" % @rule_number
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Public: Get the Integer wolfram code of the rule.
|
|
24
|
+
attr_reader :rule_number
|
|
25
|
+
|
|
26
|
+
# Public: Apply the rule on a single cell.
|
|
27
|
+
#
|
|
28
|
+
# cell_number - Integer number of the cell to apply the rule on.
|
|
29
|
+
# grid - The entire grid as an Array of Integer.
|
|
30
|
+
# study - Study instance.
|
|
31
|
+
#
|
|
32
|
+
# Returns the Integer new state of the cell for the next generation.
|
|
33
|
+
def apply_rule(cell_number, grid, study)
|
|
34
|
+
@cell_number = cell_number
|
|
35
|
+
@grid = grid
|
|
36
|
+
case study.method
|
|
37
|
+
when :random then apply_rule_with_random_method
|
|
38
|
+
when :single then apply_rule_with_single_method
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Get the Integer number part of a :wolfram_code_X pattern.
|
|
43
|
+
#
|
|
44
|
+
# pattern - Wolfram code pattern as a Symbol.
|
|
45
|
+
#
|
|
46
|
+
# Returns the Integer number part of the pattern.
|
|
47
|
+
# Exit application if the resulting number isn't between 0 and 255.
|
|
48
|
+
def self.wolfram_code(pattern)
|
|
49
|
+
pattern = pattern.to_s
|
|
50
|
+
num = pattern.delete("wolfram_code_").to_i
|
|
51
|
+
if num < 0 || num > 255
|
|
52
|
+
panic "Bad wolfram code: #{pattern}"
|
|
53
|
+
else
|
|
54
|
+
num
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Tells if a symbol follow the :wolfram_code_X pattern.
|
|
59
|
+
#
|
|
60
|
+
# symb - The Symbol to test.
|
|
61
|
+
#
|
|
62
|
+
# Returns Boolean true if sym is a :wolfram_code_X pattern.
|
|
63
|
+
def self.wolfram_code?(symb)
|
|
64
|
+
symb.is_a?(Symbol) && symb.to_s.start_with?("wolfram_code_")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
# Returns 0 or 1.
|
|
70
|
+
def apply_rule_with_random_method
|
|
71
|
+
next_generation_cell(left_cell, @grid[@cell_number], right_cell)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Get state of the cell to the left of the current one.
|
|
75
|
+
#
|
|
76
|
+
# Returns 0 or 1.
|
|
77
|
+
def left_cell
|
|
78
|
+
if @cell_number > 0
|
|
79
|
+
@grid[@cell_number - 1]
|
|
80
|
+
else
|
|
81
|
+
@grid[-1]
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Get state of the cell to the right of the current one.
|
|
86
|
+
#
|
|
87
|
+
# Returns 0 or 1.
|
|
88
|
+
def right_cell
|
|
89
|
+
if @cell_number == @grid.size - 1
|
|
90
|
+
@grid[0]
|
|
91
|
+
else
|
|
92
|
+
@grid[@cell_number + 1]
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Returns 0 or 1.
|
|
97
|
+
def apply_rule_with_single_method
|
|
98
|
+
next_generation_cell(left_cell_single, @grid[@cell_number], right_cell_single)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Returns 0 or 1.
|
|
102
|
+
def next_generation_cell(left, middle, right)
|
|
103
|
+
case [left, middle, right]
|
|
104
|
+
when [1,1,1] then @binary_string[0].to_i
|
|
105
|
+
when [1,1,0] then @binary_string[1].to_i
|
|
106
|
+
when [1,0,1] then @binary_string[2].to_i
|
|
107
|
+
when [1,0,0] then @binary_string[3].to_i
|
|
108
|
+
when [0,1,1] then @binary_string[4].to_i
|
|
109
|
+
when [0,1,0] then @binary_string[5].to_i
|
|
110
|
+
when [0,0,1] then @binary_string[6].to_i
|
|
111
|
+
when [0,0,0] then @binary_string[7].to_i
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Returns 0 or 1.
|
|
116
|
+
def left_cell_single
|
|
117
|
+
if @cell_number > 0
|
|
118
|
+
@grid[@cell_number - 1]
|
|
119
|
+
else
|
|
120
|
+
0
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Returns 0 or 1.
|
|
125
|
+
def right_cell_single
|
|
126
|
+
if @cell_number == @grid.size - 1
|
|
127
|
+
0
|
|
128
|
+
else
|
|
129
|
+
@grid[@cell_number + 1]
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Check if rule's number (@rule_number) is in the range 0..255.
|
|
134
|
+
#
|
|
135
|
+
# Returns nothing.
|
|
136
|
+
# Raises ArgumentError if rule's number isn't in the range 0..255.
|
|
137
|
+
def check_rule_number
|
|
138
|
+
unless @rule_number >= 0 and @rule_number <= 255
|
|
139
|
+
raise ArgumentError, "Bad Wolfram Code: #{number}"
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module Cellula
|
|
2
|
+
|
|
3
|
+
# Public: This class provides all it's needed to set up a study.
|
|
4
|
+
# Study's goal is to study cellular automaton.
|
|
5
|
+
#
|
|
6
|
+
# You rarely wants to initialize an Study object directly. This is
|
|
7
|
+
# because Study's creation needs a lots of parameters. It is
|
|
8
|
+
# much more simpler to create a Study object using StudyBuilder.
|
|
9
|
+
#
|
|
10
|
+
# Study's methods
|
|
11
|
+
# ---------------
|
|
12
|
+
# There is currently two kind of study's methods: random initial state
|
|
13
|
+
# (:random) and single 1 histories (:single). The following is quoted
|
|
14
|
+
# from Wikipedia:
|
|
15
|
+
#
|
|
16
|
+
# **Single 1 histories**
|
|
17
|
+
#
|
|
18
|
+
# One method used to study these automata is to follow its history
|
|
19
|
+
# with an initial state of all 0s except for a single cell with a 1.
|
|
20
|
+
# When the rule number is even (so that an input of 000 does not
|
|
21
|
+
# compute to a 1) it makes sense to interpret state at each time, t,
|
|
22
|
+
# as an integer expressed in binary, producing a sequence a(t) of
|
|
23
|
+
# integers.
|
|
24
|
+
#
|
|
25
|
+
# **Random initial state**
|
|
26
|
+
#
|
|
27
|
+
# A second way to investigate the behavior of these automata is to
|
|
28
|
+
# examine its history starting with a random state. Each computed
|
|
29
|
+
# result is placed under that results' source creating a
|
|
30
|
+
# two-dimensional representation of the system's evolution.
|
|
31
|
+
class Study
|
|
32
|
+
|
|
33
|
+
# Public: Initialize a new Study.
|
|
34
|
+
#
|
|
35
|
+
# ca_name - String name of the automaton to study.
|
|
36
|
+
# method - Symbol how to study the automaton.
|
|
37
|
+
# Default is :random.
|
|
38
|
+
# Could be one of:
|
|
39
|
+
# * :random
|
|
40
|
+
# * :single
|
|
41
|
+
# * :summed
|
|
42
|
+
# * :averaged
|
|
43
|
+
# Currently limited to :random and :single.
|
|
44
|
+
# generations - Integer number of generations to study.
|
|
45
|
+
# Default is 10.
|
|
46
|
+
def initialize(ca_name, method, generations)
|
|
47
|
+
@ca_name = ca_name
|
|
48
|
+
@method = method
|
|
49
|
+
@generations = generations
|
|
50
|
+
panic "Bad number of generations: #{generations}" if generations < 1
|
|
51
|
+
panic "Bad studying method: #{method}" if bad_studying_method
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Public: Get the String ca_name of the automaton to study.
|
|
55
|
+
attr_reader :ca_name
|
|
56
|
+
|
|
57
|
+
# Public: Set/get the Symbol studying method.
|
|
58
|
+
attr_accessor :method
|
|
59
|
+
|
|
60
|
+
# Public: Set/get the Integer number of generations to study.
|
|
61
|
+
attr_accessor :generations
|
|
62
|
+
|
|
63
|
+
def say_hello
|
|
64
|
+
"Studying #{@ca_name} with #{@method} method " +
|
|
65
|
+
"over #{@generations} generations."
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def bad_studying_method
|
|
71
|
+
@method != :random && @method != :single
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Cellula
|
|
2
|
+
|
|
3
|
+
# Public: Provides an interface to build Study objects.
|
|
4
|
+
#
|
|
5
|
+
# Examples
|
|
6
|
+
#
|
|
7
|
+
# ca = StudyBuilder.new("CA name").build
|
|
8
|
+
# ca = StudyBuilder.new("CA name").generations(99).build
|
|
9
|
+
class StudyBuilder
|
|
10
|
+
|
|
11
|
+
# Public: Initialize an new StudyBuilder.
|
|
12
|
+
#
|
|
13
|
+
# ca_name - String name of the cellular automaton that the Study
|
|
14
|
+
# wants to study.
|
|
15
|
+
def initialize(ca_name)
|
|
16
|
+
@ca_name = ca_name
|
|
17
|
+
@method = :random
|
|
18
|
+
@generations = 10
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Public: Set the Symbol method of study.
|
|
22
|
+
# Default is :random.
|
|
23
|
+
#
|
|
24
|
+
# Returns self.
|
|
25
|
+
def method(val); @method = val; self; end
|
|
26
|
+
|
|
27
|
+
# Public: Set the Integer number of generations to study.
|
|
28
|
+
# Default is 10.
|
|
29
|
+
#
|
|
30
|
+
# Returns self.
|
|
31
|
+
def generations(val); @generations = val; self; end
|
|
32
|
+
|
|
33
|
+
# Public: Builds a Study with characteristics given with
|
|
34
|
+
# the setters methods.
|
|
35
|
+
#
|
|
36
|
+
# Returns Study.
|
|
37
|
+
def build
|
|
38
|
+
Study.new(@ca_name, @method, @generations)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
metadata
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: cellula
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Xavier Nayrac
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2013-08-06 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: docile
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - '='
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 1.1.0
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - '='
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 1.1.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rspec
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: reek
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - '>='
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: coco
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 0.7.1
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - '>='
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 0.7.1
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: yard
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - '>='
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - '>='
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: yard-tomdoc
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - '>='
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - '>='
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
description: |-
|
|
98
|
+
Cellula aims to be a framework for building,
|
|
99
|
+
running and studying cellular automata.
|
|
100
|
+
email: xavier.nayrac@gmail.com
|
|
101
|
+
executables:
|
|
102
|
+
- cellula
|
|
103
|
+
extensions: []
|
|
104
|
+
extra_rdoc_files: []
|
|
105
|
+
files:
|
|
106
|
+
- lib/cellula.rb
|
|
107
|
+
- lib/cellula/automaton.rb
|
|
108
|
+
- lib/cellula/automaton_builder.rb
|
|
109
|
+
- lib/cellula/rule.rb
|
|
110
|
+
- lib/cellula/rules/rule.rb
|
|
111
|
+
- lib/cellula/rules/wolfram_code_rule.rb
|
|
112
|
+
- lib/cellula/study.rb
|
|
113
|
+
- lib/cellula/study_builder.rb
|
|
114
|
+
- bin/cellula
|
|
115
|
+
- Changelog.markdown
|
|
116
|
+
- Gemfile
|
|
117
|
+
- Gemfile.lock
|
|
118
|
+
- LICENSE
|
|
119
|
+
- README.markdown
|
|
120
|
+
- Rakefile
|
|
121
|
+
- TODO
|
|
122
|
+
- VERSION
|
|
123
|
+
homepage: https://github.com/lkdjiin/cellula
|
|
124
|
+
licenses:
|
|
125
|
+
- ''
|
|
126
|
+
metadata: {}
|
|
127
|
+
post_install_message:
|
|
128
|
+
rdoc_options: []
|
|
129
|
+
require_paths:
|
|
130
|
+
- lib
|
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
|
+
requirements:
|
|
133
|
+
- - '>='
|
|
134
|
+
- !ruby/object:Gem::Version
|
|
135
|
+
version: 2.0.0
|
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
|
+
requirements:
|
|
138
|
+
- - '>='
|
|
139
|
+
- !ruby/object:Gem::Version
|
|
140
|
+
version: '0'
|
|
141
|
+
requirements: []
|
|
142
|
+
rubyforge_project:
|
|
143
|
+
rubygems_version: 2.0.3
|
|
144
|
+
signing_key:
|
|
145
|
+
specification_version: 4
|
|
146
|
+
summary: Cellular Automata framework with a simple DSL
|
|
147
|
+
test_files: []
|
|
148
|
+
has_rdoc:
|