qdfca 1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +58 -0
- data/bin/qdfca +206 -0
- data/examples/Makefile +5 -0
- data/examples/e1/e1.csv +5 -0
- data/examples/e1/e1.dot +31 -0
- data/examples/e1/e1.ods +0 -0
- data/examples/e2/e2.csv +11 -0
- data/examples/e2/e2.dot +31 -0
- data/examples/e2/e2.ods +0 -0
- data/examples/e3/e3.csv +3 -0
- data/examples/e3/e3.dot +5 -0
- data/examples/e3/e3.ods +0 -0
- data/examples/e4/README.txt +5 -0
- data/examples/e4/e4.csv +9 -0
- data/examples/e4/e4.dot +55 -0
- data/examples/e4/e4.ods +0 -0
- metadata +71 -0
data/README.rdoc
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
= Quick-Deploy Formal Concept Analysis
|
2
|
+
|
3
|
+
Version:: 1.0
|
4
|
+
Author:: David Flater <dflater@nist.gov>
|
5
|
+
Copyright:: Public domain
|
6
|
+
License:: Unlicense
|
7
|
+
|
8
|
+
qdfca (Quick-Deploy Formal Concept Analysis) is a command-line filter that
|
9
|
+
implements Formal Concept Analysis (FCA). It is small, scriptable, and easy
|
10
|
+
to install, with no external requirements other than the standard Ruby
|
11
|
+
library. It is not designed to be efficient or scalable, but to ensure that
|
12
|
+
simple FCA tasks can be accomplished simply.
|
13
|
+
|
14
|
+
Usage: qdfca < context.csv > lattice.dot
|
15
|
+
|
16
|
+
The input is a formal context in comma-separated values (CSV) table format.
|
17
|
+
For example:
|
18
|
+
|
19
|
+
, A1, A2
|
20
|
+
Object 1, x,
|
21
|
+
Object 2, x, x
|
22
|
+
|
23
|
+
Attribute names are given by the first row. Object names are given by the
|
24
|
+
first column. An object is considered to have an attribute iff any
|
25
|
+
non-whitespace value appears in the corresponding table cell. The assumed
|
26
|
+
character encoding is UTF-8.
|
27
|
+
|
28
|
+
Most any spreadsheet application can be used to create and save a table in
|
29
|
+
this format. However, any use of escape characters or quoting to attempt to
|
30
|
+
allow values to contain commas is unsupported.
|
31
|
+
|
32
|
+
Output is produced in .dot file format to stdout.
|
33
|
+
Graphviz[http://www.graphviz.org/] and
|
34
|
+
xdot.py[https://github.com/jrfonseca/xdot.py] or other applications
|
35
|
+
supporting the DOT language can be used to view the output or render it into
|
36
|
+
various image formats.
|
37
|
+
|
38
|
+
The lattice is produced with reduced labelling. Concept labels list
|
39
|
+
attributes on the top line and objects on the bottom line if both are
|
40
|
+
applicable to a given node. Object names are parenthesized to avoid
|
41
|
+
ambiguity when only one line appears.
|
42
|
+
|
43
|
+
Four examples are installed along with the gem. On Linux they would show up
|
44
|
+
in /usr/lib64/ruby/gems/*/gems/qdfca-1/examples or a similar location.
|
45
|
+
|
46
|
+
== Legalese
|
47
|
+
|
48
|
+
Specific software products are identified in this documentation to support
|
49
|
+
reproducibility of results. Such identification does not imply
|
50
|
+
recommendation or endorsement by the National Institute of Standards and
|
51
|
+
Technology, nor does it imply that the products identified are necessarily
|
52
|
+
the best available for the purpose.
|
53
|
+
|
54
|
+
This software was developed at the National Institute of Standards and
|
55
|
+
Technology by an employee of the U.S. federal government in the course of his
|
56
|
+
official duties. Pursuant to Title 17 Section 105 of the United States Code,
|
57
|
+
this software is not subject to copyright protection and is in the public
|
58
|
+
domain.
|
data/bin/qdfca
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# 2015-02-20
|
3
|
+
#
|
4
|
+
# qdfca version 1.0
|
5
|
+
#
|
6
|
+
# A simple FCA tool for small problems. The input is a formal context in CSV
|
7
|
+
# table format. The output is a dot format digraph rendering of the concept
|
8
|
+
# lattice with reduced labelling.
|
9
|
+
|
10
|
+
|
11
|
+
# Internal data organization:
|
12
|
+
#
|
13
|
+
# Objects and attributes are identified by integers >= 0.
|
14
|
+
#
|
15
|
+
# Two different representations of objects and concepts are used. One is a
|
16
|
+
# set of attributes (integers >= 0). The other is a boolean array. The
|
17
|
+
# latter array's element i is true iff the former set includes i.
|
18
|
+
#
|
19
|
+
# Collections of objects and concepts are stored as arrays of sets.
|
20
|
+
|
21
|
+
|
22
|
+
unless ARGV.length==0
|
23
|
+
abort("Usage: qdfca < context.csv > lattice.dot")
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'set'
|
27
|
+
|
28
|
+
|
29
|
+
# ---------------- Read the CSV format input ----------------
|
30
|
+
|
31
|
+
# First line of input: get attribute names and fix number of attributes.
|
32
|
+
line = gets
|
33
|
+
abort("qdfca: failed to read first line of input") unless line
|
34
|
+
columns = line.chomp.split(',',-1)
|
35
|
+
unless columns.length > 1
|
36
|
+
abort("qdfca: no attribute names found on first line of input")
|
37
|
+
end
|
38
|
+
attribute_names = columns[1..-1].map(&:strip)
|
39
|
+
$na1 = attribute_names.length
|
40
|
+
$na0 = $na1 - 1
|
41
|
+
|
42
|
+
# Remaining lines of input: get objects.
|
43
|
+
$objects = Array.new
|
44
|
+
object_names = Array.new
|
45
|
+
lineno = 2
|
46
|
+
line = gets
|
47
|
+
while line
|
48
|
+
columns = line.chomp.split(',',-1)
|
49
|
+
unless columns.length == $na1 + 1
|
50
|
+
abort("qdfca: wrong number of attributes found on line " + lineno.to_s)
|
51
|
+
end
|
52
|
+
object_names.push(columns[0].strip)
|
53
|
+
$objects.push(Set.new((0..$na0).find_all{|i| columns[i+1].strip.length > 0}))
|
54
|
+
lineno += 1
|
55
|
+
line = gets
|
56
|
+
end
|
57
|
+
$no1 = $objects.length
|
58
|
+
abort("qdfca: zero objects read") if $no1==0
|
59
|
+
$no0 = $no1-1
|
60
|
+
|
61
|
+
|
62
|
+
# ---------------- Define FCbO functions ----------------
|
63
|
+
|
64
|
+
# The FCbO functions computeClosure and generateFrom are translated from the
|
65
|
+
# sequential algorithm given in Petr Krajca, Jan Outrata, and Vilem Vychodil,
|
66
|
+
# "Parallel Recursive Algorithm for FCA," in Radim Belohlavek and Sergei
|
67
|
+
# O. Kuznetsov (eds.), Proceedings of the Sixth International Conference on
|
68
|
+
# Concept Lattices and their Applications (CLA 2008), pp. 71-82, October
|
69
|
+
# 2008.
|
70
|
+
|
71
|
+
# The following variables are comparable to those appearing in the cited FCbO
|
72
|
+
# functions:
|
73
|
+
# a, c ... boolean vector giving an extent.
|
74
|
+
# b, d ... boolean vector giving an intent.
|
75
|
+
# y ... an attribute number.
|
76
|
+
|
77
|
+
# The following variables appearing in the cited FCbO functions were replaced
|
78
|
+
# by equivalents:
|
79
|
+
# table ... 2D array of booleans: substituted references to objects.
|
80
|
+
# rows ... table slices: substituted an equivalent reference to objects.
|
81
|
+
# m ... number of objects/rows minus 1: substituted no0.
|
82
|
+
# n ... number of attributes/columns minus 1: substituted na0.
|
83
|
+
|
84
|
+
# Finally, the variable concepts was added to allow the results of
|
85
|
+
# generateFrom to be returned.
|
86
|
+
|
87
|
+
def computeClosure(a, b, y)
|
88
|
+
c = Array.new($no1, false)
|
89
|
+
d = Array.new($na1, true)
|
90
|
+
for i in 0..$no0
|
91
|
+
if a[i] and $objects[i].include?(y)
|
92
|
+
c[i] = true
|
93
|
+
for j in 0..$na0
|
94
|
+
unless $objects[i].include?(j)
|
95
|
+
d[j] = false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
return c,d
|
101
|
+
end
|
102
|
+
|
103
|
+
def generateFrom(a, b, y)
|
104
|
+
concepts = Array.new(1){Set.new((0..$na0).find_all{|i| b[i]})}
|
105
|
+
if b.any?{|x| !x} and y<=$na0
|
106
|
+
for j in y..$na0
|
107
|
+
unless b[j]
|
108
|
+
c,d = computeClosure(a,b,j)
|
109
|
+
skip = false
|
110
|
+
for k in 0..(j-1)
|
111
|
+
if d[k] != b[k]
|
112
|
+
skip = true
|
113
|
+
break
|
114
|
+
end
|
115
|
+
end
|
116
|
+
unless skip
|
117
|
+
concepts += generateFrom(c,d,j+1)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
return concepts
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
# ---------------- Find concepts ----------------
|
127
|
+
|
128
|
+
# Find all concepts using FCbO, starting with the infimum.
|
129
|
+
# Infimum extent = all objects.
|
130
|
+
# Infimum intent = what attributes all objects have.
|
131
|
+
infimum = $objects.reduce(&:&)
|
132
|
+
concepts = generateFrom(Array.new($no1,true),
|
133
|
+
Array.new($na1){|i| infimum.include?(i)},
|
134
|
+
0)
|
135
|
+
nc1 = concepts.length
|
136
|
+
abort("Zero concepts") if nc1==0
|
137
|
+
nc0 = nc1-1
|
138
|
+
|
139
|
+
|
140
|
+
# ---------------- Apply reduced labelling ----------------
|
141
|
+
|
142
|
+
concept_o = Array.new(nc1){|i| Set.new}
|
143
|
+
for oi in 0..$no0
|
144
|
+
oci = -1
|
145
|
+
for ci in 0..nc0
|
146
|
+
if concepts[ci].subset?($objects[oi])
|
147
|
+
if oci<0 or concepts[oci].subset?(concepts[ci])
|
148
|
+
oci = ci
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
abort("qdfca: failure finding object concept") if oci<0
|
153
|
+
concept_o[oci].add(oi)
|
154
|
+
end
|
155
|
+
concept_a = Array.new(nc1){|i| Set.new}
|
156
|
+
for ai in 0..$na0
|
157
|
+
aci = -1
|
158
|
+
for ci in 0..nc0
|
159
|
+
if concepts[ci].include?(ai)
|
160
|
+
if aci<0 or concepts[ci].subset?(concepts[aci])
|
161
|
+
aci = ci
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
abort("qdfca: failure finding attribute concept") if aci<0
|
166
|
+
concept_a[aci].add(ai)
|
167
|
+
end
|
168
|
+
concept_names = Array.new(nc1){|ci|
|
169
|
+
onames = concept_o[ci].map{|i| object_names[i]}.sort.join(",")
|
170
|
+
anames = concept_a[ci].map{|i| attribute_names[i]}.sort.join(",")
|
171
|
+
anames + ((onames.length>0 and anames.length>0) ? "\\n" : "") +
|
172
|
+
(onames.length>0 ? "(" + onames + ")" : "")
|
173
|
+
}
|
174
|
+
|
175
|
+
|
176
|
+
# ---------------- Generate dot format output ----------------
|
177
|
+
|
178
|
+
# Although we don't use arrows, we still need a directed graph to keep the
|
179
|
+
# "lattice" properly sorted.
|
180
|
+
print "digraph {\n"
|
181
|
+
print " rankdir=TB\n"
|
182
|
+
print " node [style=filled, fillcolor=skyblue]\n"
|
183
|
+
|
184
|
+
# Define node IDs and labels. With reduced labelling there will be many
|
185
|
+
# nodes with neither objects nor attributes to indicate, and consequently
|
186
|
+
# empty labels, which cannot be distinguished without a separate ID.
|
187
|
+
for ci in 0..nc0
|
188
|
+
print " ", ci.to_s, " [label=\"", concept_names[ci], "\"]\n"
|
189
|
+
end
|
190
|
+
|
191
|
+
# Nodes (concepts) were found by FCbO, but we now use brute force and
|
192
|
+
# ignorance to find the lines. The lines correspond to the transitive
|
193
|
+
# reduction of the subset relationships. An alternative approach is to
|
194
|
+
# dumbly output every single subset relationship and then run the (maybe very
|
195
|
+
# large) result through graphviz's transitive reduction filter, tred.
|
196
|
+
for src in 0..nc0
|
197
|
+
for dst in 0..nc0
|
198
|
+
if concepts[src].proper_subset?(concepts[dst]) and
|
199
|
+
not concepts.any?{|spoiler|
|
200
|
+
concepts[src].proper_subset?(spoiler) and
|
201
|
+
spoiler.proper_subset?(concepts[dst])}
|
202
|
+
print " ", src.to_s, " -> ", dst.to_s, " [dir=none]\n"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
print "}\n"
|
data/examples/Makefile
ADDED
data/examples/e1/e1.csv
ADDED
data/examples/e1/e1.dot
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
digraph {
|
2
|
+
rankdir=TB
|
3
|
+
node [style=filled, fillcolor=skyblue]
|
4
|
+
0 [label=""]
|
5
|
+
1 [label="∼◇p\n(Contradiction)"]
|
6
|
+
2 [label=""]
|
7
|
+
3 [label="∼p"]
|
8
|
+
4 [label="(Counterfactual)"]
|
9
|
+
5 [label="◇∼p"]
|
10
|
+
6 [label=""]
|
11
|
+
7 [label="(Fact)"]
|
12
|
+
8 [label="◇p"]
|
13
|
+
9 [label="p"]
|
14
|
+
10 [label="◽p\n(Tautology)"]
|
15
|
+
0 -> 5 [dir=none]
|
16
|
+
0 -> 8 [dir=none]
|
17
|
+
1 -> 2 [dir=none]
|
18
|
+
3 -> 1 [dir=none]
|
19
|
+
3 -> 4 [dir=none]
|
20
|
+
4 -> 2 [dir=none]
|
21
|
+
5 -> 3 [dir=none]
|
22
|
+
5 -> 6 [dir=none]
|
23
|
+
6 -> 4 [dir=none]
|
24
|
+
6 -> 7 [dir=none]
|
25
|
+
7 -> 2 [dir=none]
|
26
|
+
8 -> 6 [dir=none]
|
27
|
+
8 -> 9 [dir=none]
|
28
|
+
9 -> 7 [dir=none]
|
29
|
+
9 -> 10 [dir=none]
|
30
|
+
10 -> 2 [dir=none]
|
31
|
+
}
|
data/examples/e1/e1.ods
ADDED
Binary file
|
data/examples/e2/e2.csv
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
,Know ∼◇p,Know ∼p,Know ◇∼p,Know ◇p,Know p,Know ◽p
|
2
|
+
Unknown,,,,,,
|
3
|
+
Negative possibility,,,x,,,
|
4
|
+
Possibility,,,,x,,
|
5
|
+
Falsehood,,x,x,,,
|
6
|
+
Uncertainty,,,x,x,,
|
7
|
+
Truth,,,,x,x,
|
8
|
+
Contradiction,x,x,x,,,
|
9
|
+
Counterfactual,,x,x,x,,
|
10
|
+
Fact,,,x,x,x,
|
11
|
+
Tautology,,,,x,x,x
|
data/examples/e2/e2.dot
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
digraph {
|
2
|
+
rankdir=TB
|
3
|
+
node [style=filled, fillcolor=skyblue]
|
4
|
+
0 [label="(Unknown)"]
|
5
|
+
1 [label="Know ∼◇p\n(Contradiction)"]
|
6
|
+
2 [label=""]
|
7
|
+
3 [label="Know ∼p\n(Falsehood)"]
|
8
|
+
4 [label="(Counterfactual)"]
|
9
|
+
5 [label="Know ◇∼p\n(Negative possibility)"]
|
10
|
+
6 [label="(Uncertainty)"]
|
11
|
+
7 [label="(Fact)"]
|
12
|
+
8 [label="Know ◇p\n(Possibility)"]
|
13
|
+
9 [label="Know p\n(Truth)"]
|
14
|
+
10 [label="Know ◽p\n(Tautology)"]
|
15
|
+
0 -> 5 [dir=none]
|
16
|
+
0 -> 8 [dir=none]
|
17
|
+
1 -> 2 [dir=none]
|
18
|
+
3 -> 1 [dir=none]
|
19
|
+
3 -> 4 [dir=none]
|
20
|
+
4 -> 2 [dir=none]
|
21
|
+
5 -> 3 [dir=none]
|
22
|
+
5 -> 6 [dir=none]
|
23
|
+
6 -> 4 [dir=none]
|
24
|
+
6 -> 7 [dir=none]
|
25
|
+
7 -> 2 [dir=none]
|
26
|
+
8 -> 6 [dir=none]
|
27
|
+
8 -> 9 [dir=none]
|
28
|
+
9 -> 7 [dir=none]
|
29
|
+
9 -> 10 [dir=none]
|
30
|
+
10 -> 2 [dir=none]
|
31
|
+
}
|
data/examples/e2/e2.ods
ADDED
Binary file
|
data/examples/e3/e3.csv
ADDED
data/examples/e3/e3.dot
ADDED
data/examples/e3/e3.ods
ADDED
Binary file
|
data/examples/e4/e4.csv
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
,needs water to live,lives in water,lives on land,needs chlorophyll,dicotyledon,monocotyledon,can move,has limbs,breast feeds
|
2
|
+
fish leech,x,x,,,,,x,,
|
3
|
+
bream,x,x,,,,,x,x,
|
4
|
+
frog,x,x,x,,,,x,x,
|
5
|
+
dog,x,,x,,,,x,x,x
|
6
|
+
water weeds,x,x,,x,,x,,,
|
7
|
+
reed,x,x,x,x,,x,,,
|
8
|
+
bean,x,,x,x,x,,,,
|
9
|
+
corn,x,,x,x,,x,,,
|
data/examples/e4/e4.dot
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
digraph {
|
2
|
+
rankdir=TB
|
3
|
+
node [style=filled, fillcolor=skyblue]
|
4
|
+
0 [label="needs water to live"]
|
5
|
+
1 [label="lives in water"]
|
6
|
+
2 [label=""]
|
7
|
+
3 [label="(reed)"]
|
8
|
+
4 [label=""]
|
9
|
+
5 [label="(frog)"]
|
10
|
+
6 [label="(water weeds)"]
|
11
|
+
7 [label="(fish leech)"]
|
12
|
+
8 [label="(bream)"]
|
13
|
+
9 [label="lives on land"]
|
14
|
+
10 [label=""]
|
15
|
+
11 [label="dicotyledon\n(bean)"]
|
16
|
+
12 [label="(corn)"]
|
17
|
+
13 [label=""]
|
18
|
+
14 [label="breast feeds\n(dog)"]
|
19
|
+
15 [label="needs chlorophyll"]
|
20
|
+
16 [label="monocotyledon"]
|
21
|
+
17 [label="can move"]
|
22
|
+
18 [label="has limbs"]
|
23
|
+
0 -> 1 [dir=none]
|
24
|
+
0 -> 9 [dir=none]
|
25
|
+
0 -> 15 [dir=none]
|
26
|
+
0 -> 17 [dir=none]
|
27
|
+
1 -> 2 [dir=none]
|
28
|
+
1 -> 6 [dir=none]
|
29
|
+
1 -> 7 [dir=none]
|
30
|
+
2 -> 3 [dir=none]
|
31
|
+
2 -> 5 [dir=none]
|
32
|
+
3 -> 4 [dir=none]
|
33
|
+
5 -> 4 [dir=none]
|
34
|
+
6 -> 3 [dir=none]
|
35
|
+
7 -> 8 [dir=none]
|
36
|
+
8 -> 5 [dir=none]
|
37
|
+
9 -> 2 [dir=none]
|
38
|
+
9 -> 10 [dir=none]
|
39
|
+
9 -> 13 [dir=none]
|
40
|
+
10 -> 11 [dir=none]
|
41
|
+
10 -> 12 [dir=none]
|
42
|
+
11 -> 4 [dir=none]
|
43
|
+
12 -> 3 [dir=none]
|
44
|
+
13 -> 5 [dir=none]
|
45
|
+
13 -> 14 [dir=none]
|
46
|
+
14 -> 4 [dir=none]
|
47
|
+
15 -> 10 [dir=none]
|
48
|
+
15 -> 16 [dir=none]
|
49
|
+
16 -> 6 [dir=none]
|
50
|
+
16 -> 12 [dir=none]
|
51
|
+
17 -> 7 [dir=none]
|
52
|
+
17 -> 18 [dir=none]
|
53
|
+
18 -> 8 [dir=none]
|
54
|
+
18 -> 13 [dir=none]
|
55
|
+
}
|
data/examples/e4/e4.ods
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: qdfca
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Flater
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-02-20 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: qdfca (Quick-Deploy Formal Concept Analysis) is a command-line filter
|
15
|
+
that implements Formal Concept Analysis (FCA). It is small, scriptable, and easy
|
16
|
+
to install, with no external requirements other than the standard Ruby library. The
|
17
|
+
input is a formal context in CSV table format. The output is a dot format digraph
|
18
|
+
rendering of the concept lattice with reduced labelling.
|
19
|
+
email: dflater@nist.gov
|
20
|
+
executables:
|
21
|
+
- qdfca
|
22
|
+
extensions: []
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README.rdoc
|
25
|
+
files:
|
26
|
+
- bin/qdfca
|
27
|
+
- README.rdoc
|
28
|
+
- examples/Makefile
|
29
|
+
- examples/e1/e1.dot
|
30
|
+
- examples/e1/e1.csv
|
31
|
+
- examples/e1/e1.ods
|
32
|
+
- examples/e2/e2.csv
|
33
|
+
- examples/e2/e2.ods
|
34
|
+
- examples/e2/e2.dot
|
35
|
+
- examples/e3/e3.ods
|
36
|
+
- examples/e3/e3.dot
|
37
|
+
- examples/e3/e3.csv
|
38
|
+
- examples/e4/README.txt
|
39
|
+
- examples/e4/e4.csv
|
40
|
+
- examples/e4/e4.ods
|
41
|
+
- examples/e4/e4.dot
|
42
|
+
homepage: http://www.nist.gov/itl/ssd/cs/software-performance.cfm
|
43
|
+
licenses:
|
44
|
+
- Unlicense
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options:
|
47
|
+
- --main
|
48
|
+
- README.rdoc
|
49
|
+
- --title
|
50
|
+
- Quick-Deploy Formal Concept Analysis (FCA)
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: 1.9.3
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.8.23
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: Quick-Deploy Formal Concept Analysis (FCA)
|
71
|
+
test_files: []
|