fuzzy-logic 0.0.1
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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +36 -0
- data/Guardfile +24 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +7 -0
- data/demo/fuzzy-demo.rb +22 -0
- data/demo/fuzzy-demo2.rb +40 -0
- data/demo/output-fuzzy-demo.txt +93 -0
- data/fuzzy-logic.gemspec +22 -0
- data/lib/fuzzy-logic/collection.rb +36 -0
- data/lib/fuzzy-logic/generate.rb +76 -0
- data/lib/fuzzy-logic/set.rb +44 -0
- data/lib/fuzzy-logic.rb +38 -0
- data/prototype/fuzzy-prototype.rb +49 -0
- data/prototype/output-fuzzy-prototype.txt +128 -0
- data/spec/fuzzy-logic/collection_spec.rb +78 -0
- data/spec/fuzzy-logic/generate_spec.rb +75 -0
- data/spec/fuzzy-logic/set_spec.rb +138 -0
- data/spec/fuzzy-logic/spec_helper.rb +4 -0
- data/spec/spec-helper.rb +5 -0
- metadata +95 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
fuzzy-logic (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
coderay (1.0.8)
|
10
|
+
ffi (1.3.1)
|
11
|
+
guard (1.6.1)
|
12
|
+
listen (>= 0.6.0)
|
13
|
+
lumberjack (>= 1.0.2)
|
14
|
+
pry (>= 0.9.10)
|
15
|
+
thor (>= 0.14.6)
|
16
|
+
guard-minitest (0.5.0)
|
17
|
+
guard (>= 0.4)
|
18
|
+
listen (0.7.2)
|
19
|
+
lumberjack (1.0.2)
|
20
|
+
method_source (0.8.1)
|
21
|
+
pry (0.9.10)
|
22
|
+
coderay (~> 1.0.5)
|
23
|
+
method_source (~> 0.8)
|
24
|
+
slop (~> 3.3.1)
|
25
|
+
rb-inotify (0.8.8)
|
26
|
+
ffi (>= 0.5.0)
|
27
|
+
slop (3.3.3)
|
28
|
+
thor (0.16.0)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
fuzzy-logic!
|
35
|
+
guard-minitest
|
36
|
+
rb-inotify (~> 0.8.8)
|
data/Guardfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'minitest' do
|
5
|
+
# with Minitest::Unit
|
6
|
+
watch(%r|^test/(.*)\/?test_(.*)\.rb|)
|
7
|
+
watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
|
8
|
+
watch(%r|^test/test_helper\.rb|) { "test" }
|
9
|
+
|
10
|
+
# with Minitest::Spec
|
11
|
+
watch(%r|^spec/(.*)_spec\.rb|)
|
12
|
+
watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
13
|
+
watch(%r|^spec/spec_helper\.rb|) { "spec" }
|
14
|
+
|
15
|
+
# Rails 3.2
|
16
|
+
# watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/controllers/#{m[1]}_test.rb" }
|
17
|
+
# watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
|
18
|
+
# watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
|
19
|
+
|
20
|
+
# Rails
|
21
|
+
# watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/functional/#{m[1]}_test.rb" }
|
22
|
+
# watch(%r|^app/helpers/(.*)\.rb|) { |m| "test/helpers/#{m[1]}_test.rb" }
|
23
|
+
# watch(%r|^app/models/(.*)\.rb|) { |m| "test/unit/#{m[1]}_test.rb" }
|
24
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 addisaden
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Fuzzy-Logic
|
2
|
+
|
3
|
+
Fuzzy logic is a mathematical concept of fuzzy logical sets.
|
4
|
+
An element of a fuzzy-set belongs to it in a range between zero and one.
|
5
|
+
|
6
|
+
read my [work](http://writedown.eu/wp-content/uploads/2013/01/fuzzy-logik_fuzzy-regeln.pdf) on this topic in german.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'fuzzy-logic'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install fuzzy-logic
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
TODO: Write usage instructions here
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
1. Fork it
|
29
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
30
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
31
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
32
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/demo/fuzzy-demo.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "../lib/fuzzy-logic.rb"
|
4
|
+
|
5
|
+
temp = FuzzyLogic::Collection.new("Temperatur") { |grad|
|
6
|
+
o = false
|
7
|
+
if grad < 100 and grad > -100 then
|
8
|
+
o = true
|
9
|
+
end
|
10
|
+
o
|
11
|
+
}
|
12
|
+
|
13
|
+
temp[:cold] = FuzzyLogic::Generate.trapezoid(-101,-100,5, 13)
|
14
|
+
temp[:hot] = FuzzyLogic::Generate.trapezoid(21,30,100,101)
|
15
|
+
temp[:warm] = FuzzyLogic::Generate.triangle(20, 11)
|
16
|
+
temp[:cool] = FuzzyLogic::Generate.triangle(10,11)
|
17
|
+
|
18
|
+
(0..30).to_a.each { |x|
|
19
|
+
puts "#{ x } °C"
|
20
|
+
puts temp.get(x).inspect
|
21
|
+
puts
|
22
|
+
}
|
data/demo/fuzzy-demo2.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "../lib/fuzzy-logic.rb"
|
4
|
+
|
5
|
+
tageszeit = FuzzyLogic::Collection.new("Tageszeit") { |n|
|
6
|
+
o = false
|
7
|
+
if n.is_a? Time then
|
8
|
+
o = true
|
9
|
+
end
|
10
|
+
o
|
11
|
+
}
|
12
|
+
|
13
|
+
morgens_set = FuzzyLogic::Generate.triangle(8, 7)
|
14
|
+
tageszeit[:morgen] = FuzzyLogic::Set.new(1) { |n|
|
15
|
+
morgens_set.get(n.hour + n.min/60.0)
|
16
|
+
}
|
17
|
+
|
18
|
+
mittags_set = FuzzyLogic::Generate.triangle(12, 5)
|
19
|
+
tageszeit[:mittag] = FuzzyLogic::Set.new(1) { |n|
|
20
|
+
mittags_set.get(n.hour + n.min/60.0)
|
21
|
+
}
|
22
|
+
|
23
|
+
nachmittags_set = FuzzyLogic::Generate.triangle(16, 5)
|
24
|
+
tageszeit[:nachmittag] = FuzzyLogic::Set.new(1) { |n|
|
25
|
+
nachmittags_set.get(n.hour + n.min/60.0)
|
26
|
+
}
|
27
|
+
|
28
|
+
abends_set = FuzzyLogic::Generate.triangle(20, 6)
|
29
|
+
tageszeit[:abend] = FuzzyLogic::Set.new(1) { |n|
|
30
|
+
mittags_set.get(n.hour + n.min/60.0)
|
31
|
+
}
|
32
|
+
|
33
|
+
nachts_set_A = FuzzyLogic::Generate.triangle(23.9, 4)
|
34
|
+
nachts_set_B = FuzzyLogic::Generate.trapezoid(-1,0,5,9)
|
35
|
+
tageszeit[:nacht] = FuzzyLogic::Set.new(1) { |n|
|
36
|
+
t = n.hour + n.min/60.0
|
37
|
+
[nachts_set_A.get(t), nachts_set_B.get(t)].max
|
38
|
+
}
|
39
|
+
|
40
|
+
puts "Die aktuelle Tageszeit entspricht: #{ tageszeit.get(Time.now) }"
|
@@ -0,0 +1,93 @@
|
|
1
|
+
0 °C
|
2
|
+
{:cold=>1.0}
|
3
|
+
|
4
|
+
1 °C
|
5
|
+
{:cold=>1.0}
|
6
|
+
|
7
|
+
2 °C
|
8
|
+
{:cold=>1.0}
|
9
|
+
|
10
|
+
3 °C
|
11
|
+
{:cold=>1.0}
|
12
|
+
|
13
|
+
4 °C
|
14
|
+
{:cold=>1.0}
|
15
|
+
|
16
|
+
5 °C
|
17
|
+
{:cold=>1.0, :cool=>0.09090909090909094}
|
18
|
+
|
19
|
+
6 °C
|
20
|
+
{:cold=>0.875, :cool=>0.2727272727272727}
|
21
|
+
|
22
|
+
7 °C
|
23
|
+
{:cold=>0.75, :cool=>0.4545454545454546}
|
24
|
+
|
25
|
+
8 °C
|
26
|
+
{:cold=>0.625, :cool=>0.6363636363636364}
|
27
|
+
|
28
|
+
9 °C
|
29
|
+
{:cold=>0.5, :cool=>0.8181818181818181}
|
30
|
+
|
31
|
+
10 °C
|
32
|
+
{:cold=>0.375, :cool=>1.0}
|
33
|
+
|
34
|
+
11 °C
|
35
|
+
{:cold=>0.25, :cool=>0.8181818181818181}
|
36
|
+
|
37
|
+
12 °C
|
38
|
+
{:cold=>0.125, :cool=>0.6363636363636364}
|
39
|
+
|
40
|
+
13 °C
|
41
|
+
{:cool=>0.4545454545454546}
|
42
|
+
|
43
|
+
14 °C
|
44
|
+
{:cool=>0.2727272727272727}
|
45
|
+
|
46
|
+
15 °C
|
47
|
+
{:warm=>0.09090909090909094, :cool=>0.09090909090909094}
|
48
|
+
|
49
|
+
16 °C
|
50
|
+
{:warm=>0.2727272727272727}
|
51
|
+
|
52
|
+
17 °C
|
53
|
+
{:warm=>0.4545454545454546}
|
54
|
+
|
55
|
+
18 °C
|
56
|
+
{:warm=>0.6363636363636364}
|
57
|
+
|
58
|
+
19 °C
|
59
|
+
{:warm=>0.8181818181818181}
|
60
|
+
|
61
|
+
20 °C
|
62
|
+
{:warm=>1.0}
|
63
|
+
|
64
|
+
21 °C
|
65
|
+
{:warm=>0.8181818181818181}
|
66
|
+
|
67
|
+
22 °C
|
68
|
+
{:hot=>0.11111111111111116, :warm=>0.6363636363636364}
|
69
|
+
|
70
|
+
23 °C
|
71
|
+
{:hot=>0.2222222222222222, :warm=>0.4545454545454546}
|
72
|
+
|
73
|
+
24 °C
|
74
|
+
{:hot=>0.33333333333333337, :warm=>0.2727272727272727}
|
75
|
+
|
76
|
+
25 °C
|
77
|
+
{:hot=>0.4444444444444444, :warm=>0.09090909090909094}
|
78
|
+
|
79
|
+
26 °C
|
80
|
+
{:hot=>0.5555555555555556}
|
81
|
+
|
82
|
+
27 °C
|
83
|
+
{:hot=>0.6666666666666667}
|
84
|
+
|
85
|
+
28 °C
|
86
|
+
{:hot=>0.7777777777777778}
|
87
|
+
|
88
|
+
29 °C
|
89
|
+
{:hot=>0.8888888888888888}
|
90
|
+
|
91
|
+
30 °C
|
92
|
+
{:hot=>1.0}
|
93
|
+
|
data/fuzzy-logic.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "./lib/fuzzy-logic.rb"
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "fuzzy-logic"
|
8
|
+
gem.version = FuzzyLogic::VERSION
|
9
|
+
gem.authors = ["Adrian E."]
|
10
|
+
gem.email = ["ae@writedown.eu"]
|
11
|
+
gem.description = %q{fuzzy-logic and fuzzy-rules are really handy for some problems.}
|
12
|
+
gem.summary = %q{brings fuzzy-logic and fuzzy-rules to ruby}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency('guard-minitest')
|
21
|
+
gem.add_development_dependency('rb-inotify', '~> 0.8.8')
|
22
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "../fuzzy-logic.rb"
|
4
|
+
|
5
|
+
module FuzzyLogic
|
6
|
+
class Collection
|
7
|
+
def initialize(name, &test)
|
8
|
+
@name = name
|
9
|
+
# a test for inputvariables (returns true/false)
|
10
|
+
@test = test
|
11
|
+
@sets = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def length
|
15
|
+
@sets.count
|
16
|
+
end
|
17
|
+
|
18
|
+
def []=(fuzzysetname, fuzzyset)
|
19
|
+
raise ArgumentError, "Secound argument should be a Fuzzy-Set" unless fuzzyset.is_a?Set
|
20
|
+
@sets[fuzzysetname.to_sym] = fuzzyset
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(n, all=false)
|
24
|
+
raise TypeError, "Test of Fuzzy-Collection is not valid" unless [true, false].include? @test.call(n)
|
25
|
+
raise ArgumentError, "Argument is not valid" unless @test.call(n)
|
26
|
+
sets_output = {}
|
27
|
+
@sets.each { |name, fset|
|
28
|
+
x = fset.get(n)
|
29
|
+
if x != 0 or all then
|
30
|
+
sets_output[name] = x
|
31
|
+
end
|
32
|
+
}
|
33
|
+
sets_output
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "../fuzzy-logic.rb"
|
4
|
+
|
5
|
+
module FuzzyLogic
|
6
|
+
module Generate
|
7
|
+
def self.gauss
|
8
|
+
#
|
9
|
+
# Gauss would be calculated with this expression:
|
10
|
+
#
|
11
|
+
# Math.exp(
|
12
|
+
# -( (n - center)/diffusion )**2
|
13
|
+
# )
|
14
|
+
#
|
15
|
+
# Problem: On an overange feedback are big numbers instead of zero
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.triangle(center, range)
|
19
|
+
range = range.abs
|
20
|
+
return Set.new(1) { |n|
|
21
|
+
o = 0.0
|
22
|
+
if n == center then
|
23
|
+
o = 1.0
|
24
|
+
elsif n.between?((center-range/2.0), (center+range/2.0)) then
|
25
|
+
o = 1.0 - [1.0, (n - center).abs.to_f/(range/2.0)].min
|
26
|
+
end
|
27
|
+
o
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.trapezoid(supmin, cormin, cormax, supmax)
|
32
|
+
supmin, cormin, cormax, supmax = *([supmin, cormin, cormax, supmax].sort.map(&:to_f))
|
33
|
+
return Set.new(1) { |n|
|
34
|
+
o = 0.0
|
35
|
+
if n.between?(cormin,cormax) then
|
36
|
+
o = 1.0
|
37
|
+
elsif n.between?(supmin,cormin) then
|
38
|
+
o = 1 - (cormin - n)/(cormin - supmin)
|
39
|
+
elsif n.between?(cormax,supmax) then
|
40
|
+
o = 1 - (n - cormax)/(supmax - cormax)
|
41
|
+
end
|
42
|
+
o
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.singleton(*args)
|
47
|
+
args_test_array_filled_with_arrays_length(args, "Arguments of a singleton fuzzy-set should be Arrays of length 2", 2)
|
48
|
+
|
49
|
+
args = args.sort { |a,b| a.first <=> b.first }
|
50
|
+
max = args.collect { |a| a.last } .sort.last
|
51
|
+
|
52
|
+
return Set.new(max) { |n|
|
53
|
+
o = 0.0
|
54
|
+
args.each { |a|
|
55
|
+
if n == a.first then
|
56
|
+
o = a.last.to_f
|
57
|
+
break
|
58
|
+
end
|
59
|
+
}
|
60
|
+
o
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.list(*args)
|
65
|
+
args_test_array_filled_with_arrays_length(args, "Arguments of a list fuzzy-set should be Arrays of length 2", 2)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def self.args_test_array_filled_with_arrays_length(args, msg, len)
|
71
|
+
raise ArgumentError, msg unless args.select { |arg|
|
72
|
+
(not arg.is_a? Array) or (not arg.length == len)
|
73
|
+
}.empty?
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "../fuzzy-logic.rb"
|
4
|
+
|
5
|
+
module FuzzyLogic
|
6
|
+
class Set
|
7
|
+
attr_reader :height
|
8
|
+
|
9
|
+
def initialize(height=nil, &fuzzyproc)
|
10
|
+
if height != nil then
|
11
|
+
raise ArgumentError, "Initial Height should be numeric" unless height.is_a? Numeric
|
12
|
+
raise ArgumentError, "Initial Height should be between 0 and 1" if height < 0 or height > 1
|
13
|
+
end
|
14
|
+
@fuzzyproc = fuzzyproc
|
15
|
+
@height = height
|
16
|
+
end
|
17
|
+
|
18
|
+
def support(value, alphacut=nil)
|
19
|
+
get(value, alphacut) > 0
|
20
|
+
end
|
21
|
+
|
22
|
+
def core(value, alphacut=nil)
|
23
|
+
get(value, alphacut) == 1
|
24
|
+
end
|
25
|
+
|
26
|
+
def get(value, alphacut=nil)
|
27
|
+
raise ArgumentError, "Value of fuzzy-set should be Comparable" unless value.is_a? Comparable
|
28
|
+
out = @fuzzyproc.call(value)
|
29
|
+
|
30
|
+
raise TypeError, "Output of fuzzy-set should be Numeric" unless out.is_a? Numeric
|
31
|
+
raise TypeError, "Output of fuzzy-set is out of range. Should be between 0 and 1" if out < 0 or out > 1
|
32
|
+
|
33
|
+
@height ||= out
|
34
|
+
@height = out if out > @height
|
35
|
+
|
36
|
+
if alphacut then
|
37
|
+
raise ArgumentError, "Alphacut of fuzzy-set should be Comparable" unless alphacut.is_a? Numeric
|
38
|
+
out = 0 if alphacut > out
|
39
|
+
end
|
40
|
+
|
41
|
+
return out
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/fuzzy-logic.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
=begin
|
4
|
+
|
5
|
+
TODO: Build a Fuzzy-Set-Generator with a list as arguments ...
|
6
|
+
|
7
|
+
temp[:warm] = fuzzy_set_generator( [28,1], [15,0] )
|
8
|
+
temp[:cold] = fuzzy_set_generator( [0, 1], [15,0] )
|
9
|
+
|
10
|
+
temp[:mid] = fuzzy_set_and(fuzzy_set_complement(temp[:warm]), fuzzy_set_complement(temp[:cold]))
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
Generate a better view ...
|
15
|
+
|
16
|
+
TODO: Optimize Output to something like This:
|
17
|
+
|
18
|
+
0 3 6 9 12 15 18 21 24 27 30
|
19
|
+
---~~~+++oooOOO warm
|
20
|
+
OOOooo+++~~~--- cold
|
21
|
+
|
22
|
+
X <= >
|
23
|
+
O - 1.-.8
|
24
|
+
o - .8-.6
|
25
|
+
+ - .6-.4
|
26
|
+
~ - .4-.2
|
27
|
+
- - .2-.0
|
28
|
+
- .0
|
29
|
+
|
30
|
+
=end
|
31
|
+
|
32
|
+
require_relative "fuzzy-logic/set.rb"
|
33
|
+
require_relative "fuzzy-logic/generate.rb"
|
34
|
+
require_relative "fuzzy-logic/collection.rb"
|
35
|
+
|
36
|
+
module FuzzyLogic
|
37
|
+
VERSION = "0.0.1"
|
38
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
temp = {}
|
4
|
+
|
5
|
+
temp[:warm] = Proc.new { |n|
|
6
|
+
out = 0
|
7
|
+
if n >= 28
|
8
|
+
out = 1
|
9
|
+
elsif n < 28 and n >= 15
|
10
|
+
out = 1 - (28.0-n)/(28.0-15)
|
11
|
+
end
|
12
|
+
out
|
13
|
+
}
|
14
|
+
|
15
|
+
temp[:cold] = Proc.new { |n|
|
16
|
+
out = 0
|
17
|
+
if n <= 0
|
18
|
+
out = 1
|
19
|
+
elsif n < 15 and n >= 0
|
20
|
+
out = 1 - n/15.0
|
21
|
+
end
|
22
|
+
out
|
23
|
+
}
|
24
|
+
|
25
|
+
temp[:mid] = Proc.new { |n|
|
26
|
+
[(1 - temp[:cold].call(n)),(1 - temp[:warm].call(n))].min
|
27
|
+
}
|
28
|
+
|
29
|
+
temp[:cool] = Proc.new { |n|
|
30
|
+
temp[:mid].call(n)*temp[:cold].call(n)*4
|
31
|
+
}
|
32
|
+
|
33
|
+
|
34
|
+
(0..30).to_a.each { |inp|
|
35
|
+
next if inp % 2 == 1
|
36
|
+
puts "--- Testing #{ inp } °C"
|
37
|
+
|
38
|
+
tp = nil
|
39
|
+
|
40
|
+
temp.each { |n,f|
|
41
|
+
tp ||= [n, f.call(inp)]
|
42
|
+
if f.call(inp) > tp.last then
|
43
|
+
tp = [n, f.call(inp)]
|
44
|
+
end
|
45
|
+
puts "Is the weather #{ n }?\t%.2f" % f.call(inp)
|
46
|
+
}
|
47
|
+
|
48
|
+
puts "\nOn #{inp} °C the weather is #{ tp.first }!\n\n"
|
49
|
+
}
|
@@ -0,0 +1,128 @@
|
|
1
|
+
--- Testing 0 °C
|
2
|
+
Is the weather warm? 0.00
|
3
|
+
Is the weather cold? 1.00
|
4
|
+
Is the weather mid? 0.00
|
5
|
+
Is the weather cool? 0.00
|
6
|
+
|
7
|
+
On 0 °C the weather is cold!
|
8
|
+
|
9
|
+
--- Testing 2 °C
|
10
|
+
Is the weather warm? 0.00
|
11
|
+
Is the weather cold? 0.87
|
12
|
+
Is the weather mid? 0.13
|
13
|
+
Is the weather cool? 0.46
|
14
|
+
|
15
|
+
On 2 °C the weather is cold!
|
16
|
+
|
17
|
+
--- Testing 4 °C
|
18
|
+
Is the weather warm? 0.00
|
19
|
+
Is the weather cold? 0.73
|
20
|
+
Is the weather mid? 0.27
|
21
|
+
Is the weather cool? 0.78
|
22
|
+
|
23
|
+
On 4 °C the weather is cool!
|
24
|
+
|
25
|
+
--- Testing 6 °C
|
26
|
+
Is the weather warm? 0.00
|
27
|
+
Is the weather cold? 0.60
|
28
|
+
Is the weather mid? 0.40
|
29
|
+
Is the weather cool? 0.96
|
30
|
+
|
31
|
+
On 6 °C the weather is cool!
|
32
|
+
|
33
|
+
--- Testing 8 °C
|
34
|
+
Is the weather warm? 0.00
|
35
|
+
Is the weather cold? 0.47
|
36
|
+
Is the weather mid? 0.53
|
37
|
+
Is the weather cool? 1.00
|
38
|
+
|
39
|
+
On 8 °C the weather is cool!
|
40
|
+
|
41
|
+
--- Testing 10 °C
|
42
|
+
Is the weather warm? 0.00
|
43
|
+
Is the weather cold? 0.33
|
44
|
+
Is the weather mid? 0.67
|
45
|
+
Is the weather cool? 0.89
|
46
|
+
|
47
|
+
On 10 °C the weather is cool!
|
48
|
+
|
49
|
+
--- Testing 12 °C
|
50
|
+
Is the weather warm? 0.00
|
51
|
+
Is the weather cold? 0.20
|
52
|
+
Is the weather mid? 0.80
|
53
|
+
Is the weather cool? 0.64
|
54
|
+
|
55
|
+
On 12 °C the weather is mid!
|
56
|
+
|
57
|
+
--- Testing 14 °C
|
58
|
+
Is the weather warm? 0.00
|
59
|
+
Is the weather cold? 0.07
|
60
|
+
Is the weather mid? 0.93
|
61
|
+
Is the weather cool? 0.25
|
62
|
+
|
63
|
+
On 14 °C the weather is mid!
|
64
|
+
|
65
|
+
--- Testing 16 °C
|
66
|
+
Is the weather warm? 0.08
|
67
|
+
Is the weather cold? 0.00
|
68
|
+
Is the weather mid? 0.92
|
69
|
+
Is the weather cool? 0.00
|
70
|
+
|
71
|
+
On 16 °C the weather is mid!
|
72
|
+
|
73
|
+
--- Testing 18 °C
|
74
|
+
Is the weather warm? 0.23
|
75
|
+
Is the weather cold? 0.00
|
76
|
+
Is the weather mid? 0.77
|
77
|
+
Is the weather cool? 0.00
|
78
|
+
|
79
|
+
On 18 °C the weather is mid!
|
80
|
+
|
81
|
+
--- Testing 20 °C
|
82
|
+
Is the weather warm? 0.38
|
83
|
+
Is the weather cold? 0.00
|
84
|
+
Is the weather mid? 0.62
|
85
|
+
Is the weather cool? 0.00
|
86
|
+
|
87
|
+
On 20 °C the weather is mid!
|
88
|
+
|
89
|
+
--- Testing 22 °C
|
90
|
+
Is the weather warm? 0.54
|
91
|
+
Is the weather cold? 0.00
|
92
|
+
Is the weather mid? 0.46
|
93
|
+
Is the weather cool? 0.00
|
94
|
+
|
95
|
+
On 22 °C the weather is warm!
|
96
|
+
|
97
|
+
--- Testing 24 °C
|
98
|
+
Is the weather warm? 0.69
|
99
|
+
Is the weather cold? 0.00
|
100
|
+
Is the weather mid? 0.31
|
101
|
+
Is the weather cool? 0.00
|
102
|
+
|
103
|
+
On 24 °C the weather is warm!
|
104
|
+
|
105
|
+
--- Testing 26 °C
|
106
|
+
Is the weather warm? 0.85
|
107
|
+
Is the weather cold? 0.00
|
108
|
+
Is the weather mid? 0.15
|
109
|
+
Is the weather cool? 0.00
|
110
|
+
|
111
|
+
On 26 °C the weather is warm!
|
112
|
+
|
113
|
+
--- Testing 28 °C
|
114
|
+
Is the weather warm? 1.00
|
115
|
+
Is the weather cold? 0.00
|
116
|
+
Is the weather mid? 0.00
|
117
|
+
Is the weather cool? 0.00
|
118
|
+
|
119
|
+
On 28 °C the weather is warm!
|
120
|
+
|
121
|
+
--- Testing 30 °C
|
122
|
+
Is the weather warm? 1.00
|
123
|
+
Is the weather cold? 0.00
|
124
|
+
Is the weather mid? 0.00
|
125
|
+
Is the weather cool? 0.00
|
126
|
+
|
127
|
+
On 30 °C the weather is warm!
|
128
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "spec_helper.rb"
|
4
|
+
require "minitest/autorun"
|
5
|
+
|
6
|
+
describe FuzzyLogic::Collection do
|
7
|
+
before do
|
8
|
+
@collection = FuzzyLogic::Collection.new("Collection Test") { |t|
|
9
|
+
o = true
|
10
|
+
if not t.is_a? Numeric then
|
11
|
+
o = false
|
12
|
+
elsif t < 0 or t > 100 then
|
13
|
+
o = false
|
14
|
+
end
|
15
|
+
o
|
16
|
+
}
|
17
|
+
|
18
|
+
@empty_collection = FuzzyLogic::Collection.new("Empty-Collection Test") { |t|
|
19
|
+
true
|
20
|
+
}
|
21
|
+
|
22
|
+
@wrong_test_collection = FuzzyLogic::Collection.new("Wrong-Proc-Test in Collection Test") { |n|
|
23
|
+
42
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "can add a fuzzyset" do
|
28
|
+
it "should work like a normal hash" do
|
29
|
+
@collection[:test] = FuzzyLogic::Generate.trapezoid(10,20,30,40)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should throw an error when get not FuzzySet" do
|
33
|
+
lambda { @collection[:no_fuzzy_set] = 13 }.must_raise ArgumentError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "give a hash on a value" do
|
38
|
+
before do
|
39
|
+
@collection[:test] = FuzzyLogic::Generate.trapezoid(10,20,30,40)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "wont be empty on 25 (or 0 with true)" do
|
43
|
+
@collection.get(25).wont_be_empty
|
44
|
+
@collection.get(0, true).wont_be_empty
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should be empty on 0" do
|
48
|
+
@collection.get(0).must_be_empty
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should raise an error with wrong arguments" do
|
52
|
+
lambda { @collection.get("Hallo") }.must_raise ArgumentError
|
53
|
+
lambda { @collection.get(-1) }.must_raise ArgumentError
|
54
|
+
lambda { @collection.get(100.01) }.must_raise ArgumentError
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should have a .length of one" do
|
58
|
+
@collection.length.must_equal 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "an empty collection" do
|
63
|
+
it "should give an empty Hash on .get" do
|
64
|
+
@empty_collection.get(1).must_be :is_a?, Hash
|
65
|
+
@empty_collection.get(1).must_be_empty
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should give a .length of zero" do
|
69
|
+
@empty_collection.length.must_equal 0
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "a collection with a wrong test" do
|
74
|
+
it "should give a TypeError on get" do
|
75
|
+
lambda { @wrong_test_collection.get(1) }.must_raise TypeError
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "spec_helper.rb"
|
4
|
+
require "minitest/autorun"
|
5
|
+
|
6
|
+
describe FuzzyLogic::Generate do
|
7
|
+
before do
|
8
|
+
# @gauss
|
9
|
+
@triangle = FuzzyLogic::Generate.triangle(10,10)
|
10
|
+
@trapezoid = FuzzyLogic::Generate.trapezoid(10,20,30,40)
|
11
|
+
# @list
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "a gauss fuzzy-set" do
|
15
|
+
# no test yet - no architecture ...
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "a triangle fuzzy-set" do
|
19
|
+
it "should have a point with 1" do
|
20
|
+
@triangle.get(10).must_equal 1
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have also some valuse near one" do
|
24
|
+
@triangle.get(9.9).must_be :<, 1
|
25
|
+
@triangle.get(9.9).must_be :>, 0.8
|
26
|
+
@triangle.get(10.1).must_be :<, 1
|
27
|
+
@triangle.get(10.1).must_be :>, 0.8
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have also some valuse near zero" do
|
31
|
+
@triangle.get(5.1).must_be :>, 0
|
32
|
+
@triangle.get(5.1).must_be :<, 0.2
|
33
|
+
@triangle.get(14.9).must_be :>, 0
|
34
|
+
@triangle.get(14.9).must_be :<, 0.2
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have a zone with 0" do
|
38
|
+
[5,0,-15,15,20].each { |t|
|
39
|
+
@triangle.get(t).must_equal 0
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "a trapezoid fuzzy-set" do
|
45
|
+
it "should have a zone with 1" do
|
46
|
+
[20,25,30].each { |t|
|
47
|
+
@trapezoid.get(t).must_equal 1
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should have also some values near one" do
|
52
|
+
@trapezoid.get(19.9).must_be :<, 1
|
53
|
+
@trapezoid.get(19.9).must_be :>, 0.9
|
54
|
+
@trapezoid.get(30.1).must_be :<, 1
|
55
|
+
@trapezoid.get(30.1).must_be :>, 0.9
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should have also some values near zero" do
|
59
|
+
@trapezoid.get(10.1).must_be :>, 0
|
60
|
+
@trapezoid.get(10.1).must_be :<, 0.1
|
61
|
+
@trapezoid.get(39.9).must_be :>, 0
|
62
|
+
@trapezoid.get(39.9).must_be :<, 0.1
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should have a zone with 0" do
|
66
|
+
[0, 5, 10, 40, 41, 49, 50].each { |t|
|
67
|
+
@trapezoid.get(t).must_equal 0
|
68
|
+
}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "a list fuzzy-set" do
|
73
|
+
# no test yet - no architecture ...
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative "spec_helper.rb"
|
4
|
+
require "minitest/autorun"
|
5
|
+
|
6
|
+
describe FuzzyLogic::Set do
|
7
|
+
before do
|
8
|
+
@valid_set = FuzzyLogic::Set.new(1) { |n|
|
9
|
+
o = 0.0
|
10
|
+
o = 1.0 if n >= 30
|
11
|
+
o = 1.0 - (30.0 - n)/(30.0 - 20.0) if n < 30 and n >= 20
|
12
|
+
o
|
13
|
+
}
|
14
|
+
|
15
|
+
@invalid_set = FuzzyLogic::Set.new(1) { |n|
|
16
|
+
"i am invalid."
|
17
|
+
}
|
18
|
+
|
19
|
+
# Is christmas near?
|
20
|
+
@time_set = FuzzyLogic::Set.new(1) { |n|
|
21
|
+
t = Time.now
|
22
|
+
o = 0.0
|
23
|
+
if n.month == 12 and n.day <= 24 then
|
24
|
+
o = 1.0 if n.day >= 20
|
25
|
+
o = 1.0 - (24.0 - n.day)/(24.0 - 6.0) if n.day >= 6.0 and n.day < 20.0
|
26
|
+
end
|
27
|
+
o
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "when get values from a valid set" do
|
32
|
+
it "should have a respond with 1" do
|
33
|
+
@valid_set.get(30.0).must_equal 1.0
|
34
|
+
@time_set.get(Time.new(2013,12,24)).must_equal 1.0
|
35
|
+
@time_set.get(Time.new(2013,12,20)).must_equal 1.0
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should have a respond with 0" do
|
39
|
+
@valid_set.get(20).must_equal 0
|
40
|
+
@time_set.get(Time.new(2013,11)).must_equal 0
|
41
|
+
@time_set.get(Time.new(2013,12,6)).must_equal 0
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should have a respond near 0" do
|
45
|
+
[@valid_set.get(21), @time_set.get(Time.new(2013,12,7))].each { |t|
|
46
|
+
t.must_be :!=, 0
|
47
|
+
t.must_be :<, 0.3
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should have a respond near 1" do
|
52
|
+
[@valid_set.get(29), @time_set.get(Time.new(2013,12,19))].each { |t|
|
53
|
+
t.must_be :!=, 1
|
54
|
+
t.must_be :>, 0.7
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should have a height of 1" do
|
59
|
+
@valid_set.height.must_equal 1
|
60
|
+
@time_set.height.must_equal 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "when give wrong arguments" do
|
65
|
+
it "should raise an ArgumentError" do
|
66
|
+
lambda { @valid_set.get(Object.new) }.must_raise ArgumentError
|
67
|
+
lambda { @valid_set.get(2, Object.new) }.must_raise ArgumentError
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should raise an TypeError" do
|
71
|
+
lambda { @invalid_set.get(3) }.must_raise TypeError
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "should change height" do
|
76
|
+
before do
|
77
|
+
@temp_set = FuzzyLogic::Set.new(0) { |n|
|
78
|
+
o = 0.0
|
79
|
+
o = 1.0 if n > 10
|
80
|
+
o
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should change the height from zero to one" do
|
85
|
+
@temp_set.height.must_equal 0
|
86
|
+
@temp_set.get(20)
|
87
|
+
@temp_set.height.must_equal 1
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "if output/height of a set is out of range" do
|
92
|
+
it "should raise an error on invlalid output" do
|
93
|
+
lambda {
|
94
|
+
FuzzyLogic::Set.new { |n|
|
95
|
+
5
|
96
|
+
}.get(1)
|
97
|
+
}.must_raise TypeError
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should raise an ArgumentError on invalid initial height" do
|
101
|
+
lambda {
|
102
|
+
FuzzyLogic::Set.new(2) { |n|
|
103
|
+
true
|
104
|
+
}
|
105
|
+
}.must_raise ArgumentError
|
106
|
+
|
107
|
+
lambda {
|
108
|
+
FuzzyLogic::Set.new(:test) { |n|
|
109
|
+
true
|
110
|
+
}
|
111
|
+
}.must_raise ArgumentError
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "fuzzy-set .support" do
|
116
|
+
it "should give only on values above zero a true value, else false" do
|
117
|
+
@valid_set.support(21).must_equal true
|
118
|
+
@valid_set.support(20).must_equal false
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should also deal with alphacut" do
|
122
|
+
@valid_set.support(21, 0.5).must_equal false
|
123
|
+
@valid_set.support(26, 0.5).must_equal true
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "fuzzy-set .core" do
|
128
|
+
it "should give only on values equal to 1 a true value" do
|
129
|
+
@valid_set.core(30).must_equal true
|
130
|
+
@valid_set.core(29).must_equal false
|
131
|
+
end
|
132
|
+
|
133
|
+
it "shouldnt have a problem with an optional alphacut" do
|
134
|
+
@valid_set.core(30, 0.5).must_equal true
|
135
|
+
@valid_set.core(29, 0.5).must_equal false
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
data/spec/spec-helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fuzzy-logic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Adrian E.
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: guard-minitest
|
16
|
+
requirement: &82009770 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *82009770
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rb-inotify
|
27
|
+
requirement: &82009510 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.8.8
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *82009510
|
36
|
+
description: fuzzy-logic and fuzzy-rules are really handy for some problems.
|
37
|
+
email:
|
38
|
+
- ae@writedown.eu
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
extra_rdoc_files: []
|
42
|
+
files:
|
43
|
+
- .gitignore
|
44
|
+
- Gemfile
|
45
|
+
- Gemfile.lock
|
46
|
+
- Guardfile
|
47
|
+
- LICENSE.txt
|
48
|
+
- README.md
|
49
|
+
- Rakefile
|
50
|
+
- demo/fuzzy-demo.rb
|
51
|
+
- demo/fuzzy-demo2.rb
|
52
|
+
- demo/output-fuzzy-demo.txt
|
53
|
+
- fuzzy-logic.gemspec
|
54
|
+
- lib/fuzzy-logic.rb
|
55
|
+
- lib/fuzzy-logic/collection.rb
|
56
|
+
- lib/fuzzy-logic/generate.rb
|
57
|
+
- lib/fuzzy-logic/set.rb
|
58
|
+
- prototype/fuzzy-prototype.rb
|
59
|
+
- prototype/output-fuzzy-prototype.txt
|
60
|
+
- spec/fuzzy-logic/collection_spec.rb
|
61
|
+
- spec/fuzzy-logic/generate_spec.rb
|
62
|
+
- spec/fuzzy-logic/set_spec.rb
|
63
|
+
- spec/fuzzy-logic/spec_helper.rb
|
64
|
+
- spec/spec-helper.rb
|
65
|
+
homepage: ''
|
66
|
+
licenses: []
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.8.11
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: brings fuzzy-logic and fuzzy-rules to ruby
|
89
|
+
test_files:
|
90
|
+
- spec/fuzzy-logic/collection_spec.rb
|
91
|
+
- spec/fuzzy-logic/generate_spec.rb
|
92
|
+
- spec/fuzzy-logic/set_spec.rb
|
93
|
+
- spec/fuzzy-logic/spec_helper.rb
|
94
|
+
- spec/spec-helper.rb
|
95
|
+
has_rdoc:
|