fathom 0.3.7 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. data/.autotest +7 -5
  2. data/.document +2 -2
  3. data/Gemfile +9 -10
  4. data/{LICENSE → LICENSE.txt} +1 -1
  5. data/README.md +29 -90
  6. data/Rakefile +34 -32
  7. data/VERSION +1 -1
  8. data/fathom.gemspec +105 -0
  9. data/features/fathom.feature +26 -0
  10. data/features/step_definitions/fathom_steps.rb +23 -0
  11. data/features/support/env.rb +13 -0
  12. data/lib/ext/array.rb +6 -2
  13. data/lib/ext/string.rb +86 -7
  14. data/lib/fathom.rb +51 -88
  15. data/lib/fathom/behaviors/attribute_system.rb +91 -0
  16. data/lib/fathom/behaviors/context_behavior.rb +28 -0
  17. data/lib/fathom/behaviors/plugins.rb +16 -0
  18. data/lib/fathom/contexts/network_population.rb +47 -0
  19. data/lib/fathom/contexts/network_traversal.rb +4 -0
  20. data/lib/fathom/data/adjacency_matrix.rb +27 -0
  21. data/lib/fathom/data/definition.rb +22 -0
  22. data/lib/fathom/data/edge.rb +58 -0
  23. data/lib/fathom/data/network.rb +35 -0
  24. data/lib/fathom/data/outcome.rb +30 -0
  25. data/lib/fathom/data/property.rb +31 -0
  26. data/lib/fathom/data/variable.rb +59 -0
  27. data/lib/fathom/roles/general_graph_tools.rb +87 -0
  28. data/lib/fathom/roles/network_builder.rb +61 -0
  29. data/spec/fathom/behaviors/attribute_system_spec.rb +141 -0
  30. data/spec/fathom/behaviors/context_behavior_spec.rb +15 -0
  31. data/spec/fathom/behaviors/plugins_spec.rb +80 -0
  32. data/spec/fathom/contexts/network_population_spec.rb +55 -0
  33. data/spec/fathom/contexts/network_traversal_spec.rb +11 -0
  34. data/spec/fathom/data/adjacency_matrix_spec.rb +42 -0
  35. data/spec/fathom/data/definition_spec.rb +19 -0
  36. data/spec/fathom/data/edge_spec.rb +77 -0
  37. data/spec/fathom/data/network_spec.rb +72 -0
  38. data/spec/fathom/data/outcome_spec.rb +17 -0
  39. data/spec/fathom/data/property_spec.rb +17 -0
  40. data/spec/fathom/data/variable_spec.rb +101 -0
  41. data/spec/fathom/ext/array_spec.rb +17 -0
  42. data/spec/fathom/ext/string_spec.rb +90 -0
  43. data/spec/fathom/roles/general_graph_tools_spec.rb +95 -0
  44. data/spec/fathom/roles/network_builder_spec.rb +90 -0
  45. data/spec/fathom_spec.rb +28 -49
  46. data/spec/spec_helper.rb +7 -11
  47. data/spec/support/context_behavior.rb +14 -0
  48. data/spec/support/custom_matchers.rb +12 -0
  49. data/spec/support/files.rb +8 -0
  50. data/spec/support/network.yml +42 -0
  51. metadata +133 -174
  52. data/.bundle/config +0 -2
  53. data/.gitignore +0 -6
  54. data/Gemfile.lock +0 -42
  55. data/TODO.md +0 -127
  56. data/autotest/discover.rb +0 -1
  57. data/lib/ext/faster_csv.rb +0 -1
  58. data/lib/ext/open_struct.rb +0 -17
  59. data/lib/fathom/agent.rb +0 -48
  60. data/lib/fathom/agent/agent_cluster.rb +0 -23
  61. data/lib/fathom/agent/properties.rb +0 -48
  62. data/lib/fathom/archive/causal_graph.rb +0 -12
  63. data/lib/fathom/archive/concept.rb +0 -83
  64. data/lib/fathom/archive/conditional_probability_matrix.rb +0 -119
  65. data/lib/fathom/archive/inverter.rb +0 -20
  66. data/lib/fathom/archive/n2.rb +0 -198
  67. data/lib/fathom/archive/n3.rb +0 -119
  68. data/lib/fathom/archive/node.rb +0 -97
  69. data/lib/fathom/archive/noodle.rb +0 -136
  70. data/lib/fathom/archive/scratch.rb +0 -45
  71. data/lib/fathom/distributions.rb +0 -8
  72. data/lib/fathom/distributions/discrete_gaussian.rb +0 -44
  73. data/lib/fathom/distributions/discrete_uniform.rb +0 -25
  74. data/lib/fathom/distributions/gaussian.rb +0 -46
  75. data/lib/fathom/distributions/uniform.rb +0 -35
  76. data/lib/fathom/import.rb +0 -85
  77. data/lib/fathom/import/csv_import.rb +0 -59
  78. data/lib/fathom/import/import_node.rb +0 -17
  79. data/lib/fathom/import/yaml_import.rb +0 -74
  80. data/lib/fathom/knowledge_base.rb +0 -46
  81. data/lib/fathom/knowledge_base/search.rb +0 -19
  82. data/lib/fathom/monte_carlo_set.rb +0 -152
  83. data/lib/fathom/node.rb +0 -139
  84. data/lib/fathom/node/belief_node.rb +0 -121
  85. data/lib/fathom/node/cpm_node.rb +0 -100
  86. data/lib/fathom/node/data_collection.rb +0 -97
  87. data/lib/fathom/node/data_node.rb +0 -22
  88. data/lib/fathom/node/decision.rb +0 -11
  89. data/lib/fathom/node/discrete_node.rb +0 -41
  90. data/lib/fathom/node/fact.rb +0 -24
  91. data/lib/fathom/node/mc_node.rb +0 -70
  92. data/lib/fathom/node/node_extensions/enforced_name.rb +0 -12
  93. data/lib/fathom/node/node_extensions/numeric_methods.rb +0 -68
  94. data/lib/fathom/node/plausible_range.rb +0 -98
  95. data/lib/fathom/simulation.rb +0 -59
  96. data/lib/fathom/simulation/tick_methods.rb +0 -25
  97. data/lib/fathom/simulation/tick_simulation.rb +0 -12
  98. data/lib/fathom/value_description.rb +0 -79
  99. data/lib/options_hash.rb +0 -186
  100. data/spec/ext/array_spec.rb +0 -10
  101. data/spec/ext/faster_csv_spec.rb +0 -10
  102. data/spec/ext/open_struct_spec.rb +0 -20
  103. data/spec/ext/string_spec.rb +0 -7
  104. data/spec/fathom/agent/agent_cluster_spec.rb +0 -17
  105. data/spec/fathom/agent_spec.rb +0 -51
  106. data/spec/fathom/distributions/discrete_gaussian_spec.rb +0 -64
  107. data/spec/fathom/distributions/discrete_uniform_spec.rb +0 -0
  108. data/spec/fathom/distributions/gaussian_spec.rb +0 -64
  109. data/spec/fathom/distributions/uniform_spec.rb +0 -0
  110. data/spec/fathom/import/csv_import_spec.rb +0 -52
  111. data/spec/fathom/import/import_node_spec.rb +0 -10
  112. data/spec/fathom/import/yaml_import_spec.rb +0 -73
  113. data/spec/fathom/import_spec.rb +0 -36
  114. data/spec/fathom/knowledge_base_spec.rb +0 -20
  115. data/spec/fathom/monte_carlo_set_spec.rb +0 -149
  116. data/spec/fathom/node/belief_node_spec.rb +0 -180
  117. data/spec/fathom/node/cpm_node_spec.rb +0 -144
  118. data/spec/fathom/node/data_collection_spec.rb +0 -26
  119. data/spec/fathom/node/data_node_spec.rb +0 -102
  120. data/spec/fathom/node/decision_spec.rb +0 -15
  121. data/spec/fathom/node/discrete_node_spec.rb +0 -56
  122. data/spec/fathom/node/fact_spec.rb +0 -33
  123. data/spec/fathom/node/mc_node_spec.rb +0 -66
  124. data/spec/fathom/node/node_extensions/enforced_name_spec.rb +0 -15
  125. data/spec/fathom/node/node_extensions/numeric_methods_spec.rb +0 -124
  126. data/spec/fathom/node/plausible_range_spec.rb +0 -151
  127. data/spec/fathom/node_spec.rb +0 -172
  128. data/spec/fathom/simulation/tick_simulation_spec.rb +0 -32
  129. data/spec/fathom/simulation_spec.rb +0 -24
  130. data/spec/fathom/value_description_spec.rb +0 -70
  131. data/spec/support/demo.yml +0 -17
  132. data/spec/support/demo_agent.rb +0 -8
  133. data/spec/support/dummy_numeric_node.rb +0 -8
  134. data/spec/support/fact.yml +0 -11
@@ -0,0 +1,15 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe ContextBehavior do
6
+ it "should be able to set a default_class" do
7
+ @class = Class.new do
8
+ extend Plugins
9
+ plugin ContextBehavior
10
+ default_class Hash
11
+ end
12
+ obj = @class.new
13
+ obj.object.should eql({})
14
+ end
15
+ end
@@ -0,0 +1,80 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ module PluginDemoModule
6
+ module InstanceMethods
7
+ def special_instance_method
8
+ :special_instance_method
9
+ end
10
+ end
11
+
12
+ module ClassMethods
13
+ def special_class_method
14
+ :special_class_method
15
+ end
16
+
17
+ def special_configuration_method
18
+ @especially_configured = true
19
+ end
20
+
21
+ attr_reader :especially_configured
22
+ end
23
+
24
+ def self.configure(mod)
25
+ mod.special_configuration_method
26
+ end
27
+ end
28
+
29
+ module PlainDemoModule
30
+ def plain_instance_method
31
+ :plain_instance_method
32
+ end
33
+ end
34
+
35
+
36
+ describe Plugins do
37
+
38
+ before do
39
+ @class = Class.new do
40
+ extend Plugins
41
+ plugin PluginDemoModule
42
+ end
43
+ end
44
+
45
+ after(:all) do
46
+ Object.send(:remove_const, :PluginDemoModule)
47
+ Object.send(:remove_const, :PlainDemoModule)
48
+ end
49
+
50
+ it "should have a plugins array" do
51
+ @class.plugins.should eql([PluginDemoModule])
52
+ end
53
+
54
+ it "should be able to add a new plugin" do
55
+ @class.plugins.should eql([PluginDemoModule])
56
+ end
57
+
58
+ it "should make the ClassMethods available to the class" do
59
+ @class.special_class_method.should eql(:special_class_method)
60
+ end
61
+
62
+ it "should make the InstanceMethods available on an instance" do
63
+ obj = @class.new
64
+ obj.special_instance_method.should eql(:special_instance_method)
65
+ end
66
+
67
+ it "should include a plain module if it is not a Plugin (has InstanceMethods)" do
68
+ @class = Class.new do
69
+ extend Plugins
70
+ plugin PlainDemoModule
71
+ end
72
+ obj = @class.new
73
+ obj.plain_instance_method.should eql(:plain_instance_method)
74
+ end
75
+
76
+ it "should have called the configure method in the plugin" do
77
+ @class.especially_configured.should be_true
78
+ end
79
+
80
+ end
@@ -0,0 +1,55 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe NetworkPopulation do
6
+
7
+ # ====================
8
+ # = General Behavior =
9
+ # ====================
10
+ context "when acting like a context generally" do
11
+ before {@class = NetworkPopulation}
12
+ it_should_behave_like "a context"
13
+
14
+ it "should have a default_class of Network" do
15
+ @context = NetworkPopulation.new
16
+ @context.object.should be_a(Network)
17
+ end
18
+ end
19
+
20
+ # ==================
21
+ # = YAML Importing =
22
+ # ==================
23
+ context "when importing records from YAML" do
24
+ before do
25
+ @network = Network.new
26
+ @context = NetworkPopulation.new(@network)
27
+ end
28
+
29
+ it "should mixin the NetworkBuilder to the network" do
30
+ @context.object.should_receive(:extend).with(NetworkBuilder).and_return(true)
31
+ @context.object.stub(:from_hash) { true }
32
+ @context.import_records_from_yaml
33
+ end
34
+
35
+ it "should expose from_hash on the network object" do
36
+ @network.should_not respond_to(:from_hash)
37
+ @context.import_records_from_yaml
38
+ @network.should respond_to(:from_hash)
39
+ end
40
+
41
+ it "should be able to take a filename and process that." do
42
+ yaml_contents = YAML.load(network_contents_in_yaml)
43
+ YAML.should_receive(:load_file).with(network_contents_in_yaml_filename).and_return(yaml_contents)
44
+ @context.import_records_from_yaml(:filename => network_contents_in_yaml_filename)
45
+ end
46
+
47
+ it "should rely on from_hash to convert the loaded YAML values into a serialized network" do
48
+ yaml_contents = YAML.load(network_contents_in_yaml)
49
+ @network.should_receive(:from_hash).with(yaml_contents).and_return(true)
50
+ @context.import_records_from_yaml(:filename => network_contents_in_yaml_filename)
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,11 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe NetworkTraversal do
6
+
7
+ # context "when searching a directed graph" do
8
+ # before do
9
+ # @edges =
10
+ # end
11
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe AdjacencyMatrix do
6
+ before do
7
+ @am = AdjacencyMatrix.new
8
+ end
9
+
10
+ it "should use an efficient data storage method, a Hash that defaults to 0" do
11
+ store = @am.send(:instance_variable_get, :@store)
12
+ store.should be_a(Hash)
13
+ store[:not_indexed].should eql(0)
14
+ end
15
+
16
+ it "should take an arbitrary default for the store" do
17
+ am = AdjacencyMatrix.new(:arbitrary)
18
+ store = am.send(:instance_variable_get, :@store)
19
+ store[:not_indexed].should eql(:arbitrary)
20
+ end
21
+
22
+ it "should take a parent and child argument to get or set a value in the store" do
23
+ lambda{@am[1]}.should raise_error(ArgumentError, /wrong number of arguments/)
24
+ @am[1,1] = 1
25
+ @am[1,1].should eql(1)
26
+ end
27
+
28
+ it "should be an Enumerable" do
29
+ AdjacencyMatrix.included_modules.should be_include(Enumerable)
30
+ end
31
+
32
+ it "should enumerate on the store" do
33
+ @am[1,1] = 1
34
+ @am[2,1] = 1
35
+ @am.map.to_a.should eql([[[1, 1], 1], [[2, 1], 1]])
36
+ @am.each do |(parent, child), value|
37
+ child.should eql(1)
38
+ value.should eql(1)
39
+ [1,2].should be_include(parent)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe Definition do
6
+
7
+ it "should initialize a for accessor" do
8
+ Definition.should have_an_initialization_accessor_for(:for)
9
+ end
10
+
11
+ it "should initialize a given accessor" do
12
+ Definition.should have_an_initialization_accessor_for(:given)
13
+ end
14
+
15
+ it "should initialize a table accessor" do
16
+ Definition.should have_an_initialization_accessor_for(:table)
17
+ end
18
+
19
+ end
@@ -0,0 +1,77 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe Edge do
6
+
7
+ it "should initialize a is_directed accessor" do
8
+ Edge.should have_an_initialization_accessor_for(:is_directed)
9
+ end
10
+
11
+ it "should default the edge to true" do
12
+ edge = Edge.new
13
+ edge.is_directed.should be_true
14
+ end
15
+
16
+ it "should initialize a parent accessor" do
17
+ edge = Edge.new(:parent => :value)
18
+ edge.parent.should ==(Variable.new(:name => :value))
19
+ edge.parent = :value2
20
+ edge.parent.should ==(Variable.new(:name => :value2))
21
+ end
22
+
23
+ it "should initialize a child accessor" do
24
+ edge = Edge.new(:child => :value)
25
+ edge.child.should ==(Variable.new(:name => :value))
26
+ edge.child = :value2
27
+ edge.child.should ==(Variable.new(:name => :value2))
28
+ end
29
+
30
+ it "should be equal by variables" do
31
+ v1 = Variable.new(:name => :v1)
32
+ v2 = Variable.new(:name => :v2)
33
+ e1 = Edge.new(:parent => v1, :child => v2)
34
+ e2 = Edge.new(:parent => v1, :child => v2)
35
+ e1.should ==(e2)
36
+ end
37
+
38
+ it "should ensure the parent and child are a variables" do
39
+ edge = Edge.new :parent => :v1, :child => :v2
40
+ edge.parent.should ==(Variable.new(:name => :v1))
41
+ edge.child.should ==(Variable.new(:name => :v2))
42
+ end
43
+
44
+ context "when inferring an Edge" do
45
+ it "should be able to infer an Edge from an Edge" do
46
+ edge = Edge.new :parent => :v1, :child => :v2
47
+ inferred = Edge.infer(edge)
48
+ inferred.should eql(edge)
49
+ end
50
+
51
+ it "should be able to infer an Edge from an Array, [parent, child]" do
52
+ v1 = Variable.infer(:v1)
53
+ v2 = Variable.infer(:v2)
54
+ edge = Edge.infer([v1, v2])
55
+ edge.should be_a(Edge)
56
+ edge.parent.should eql(v1)
57
+ edge.child.should eql(v2)
58
+ end
59
+
60
+ it "should be able to take more than one parameter and use that as a parent, child indicator" do
61
+ v1 = Variable.infer(:v1)
62
+ v2 = Variable.infer(:v2)
63
+ edge = Edge.infer(v1, v2)
64
+ edge.should be_a(Edge)
65
+ edge.parent.should eql(v1)
66
+ edge.child.should eql(v2)
67
+ end
68
+
69
+ it "should be able to infer an Edge from a Hash" do
70
+ edge = Edge.infer :parent => :p, :child => :c
71
+ edge.parent.should be_a(Variable)
72
+ edge.parent.name.should eql(:p)
73
+ edge.child.should be_a(Variable)
74
+ edge.child.name.should eql(:c)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,72 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe Network do
6
+
7
+ it "should initialize a name accessor" do
8
+ Network.should have_an_initialization_accessor_for(:name)
9
+ end
10
+
11
+ it "should initialize a variables accessor" do
12
+ Network.should have_an_initialization_accessor_for(:variables)
13
+ end
14
+
15
+ it "should default the variables to an array" do
16
+ Network.new.variables.should eql([])
17
+ end
18
+
19
+ it "should extend Enumerable" do
20
+ Network.ancestors.should be_include(Enumerable)
21
+ end
22
+
23
+ it "should enumerate over the variables" do
24
+ n = Network.new :variables => [1,2,3]
25
+ n.map.to_a.should eql([1,2,3])
26
+ end
27
+
28
+ it "should initialize a properties accessor" do
29
+ Network.should have_an_initialization_accessor_for(:properties)
30
+ end
31
+
32
+ it "should default the properties to an Array" do
33
+ Network.new.properties.should eql([])
34
+ end
35
+
36
+ it "should initialize an edges accessor" do
37
+ Network.should have_an_initialization_accessor_for(:edges)
38
+ end
39
+
40
+ it "should default the edges to an Array" do
41
+ Network.new.edges.should eql([])
42
+ end
43
+
44
+ it "should initialize a definitions accessor" do
45
+ Network.should have_an_initialization_accessor_for(:definitions)
46
+ end
47
+
48
+ it "should default the definitions to an Array" do
49
+ Network.new.definitions.should eql([])
50
+ end
51
+
52
+ context "when using the Enumerator" do
53
+ before do
54
+ @n = Network.new :variables => [1,2,3]
55
+ @variables = @n.variables
56
+ end
57
+
58
+ it "should be able to iterate on the variables" do
59
+ @n.each {|v| @variables.should be_include(v)}
60
+ end
61
+
62
+ it "should have each_variable as an alias to each" do
63
+ @n.each_variable {|v| @variables.should be_include(v)}
64
+ end
65
+
66
+ it "should use the variable enumeration for the Enumerable" do
67
+ @n.map {|v| v }.should eql([1,2,3])
68
+ end
69
+ end
70
+
71
+ end
72
+
@@ -0,0 +1,17 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe Outcome do
6
+
7
+ it "should initialize a value accessor" do
8
+ Outcome.should have_an_initialization_accessor_for(:value)
9
+ end
10
+
11
+ it "should have an infer constructor" do
12
+ outcome = Outcome.infer(:some_value)
13
+ outcome.should be_a(Outcome)
14
+ outcome.value.should eql(:some_value)
15
+ end
16
+
17
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe Property do
6
+
7
+ it "should initialize a value accessor" do
8
+ Property.should have_an_initialization_accessor_for(:value)
9
+ end
10
+
11
+ it "should have an infer constructor" do
12
+ property = Property.infer(:some_value)
13
+ property.should be_a(Property)
14
+ property.value.should eql(:some_value)
15
+ end
16
+
17
+ end
@@ -0,0 +1,101 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ include Fathom
4
+
5
+ describe Variable do
6
+
7
+ # ==================
8
+ # = Initialization =
9
+ # ==================
10
+ it "should have an attributes getter, built from initialization" do
11
+ v = Variable.new(some: :value)
12
+ v.attributes.delete(:id)
13
+ v.attributes.should eql({:some => :value, :prior_odds => [0.5, 0.5]})
14
+ end
15
+
16
+ it "should initialize a name accessor" do
17
+ Variable.should have_an_initialization_accessor_for(:name)
18
+ end
19
+
20
+ it "should have an underscored_name" do
21
+ v = Variable.new(:name => "a Very special name, don't you think?")
22
+ v.underscored_name.should eql("a_very_special_name__don_t_you_think_")
23
+ end
24
+
25
+ it "should initialize a properties accessor" do
26
+ Variable.should have_an_initialization_accessor_for(:properties)
27
+ end
28
+
29
+ it "should initialize an outcomes accessor" do
30
+ Variable.should have_an_initialization_accessor_for(:outcomes)
31
+ end
32
+
33
+ it "should default the outcomes to [true, false]" do
34
+ v = Variable.new
35
+ v.outcomes.should eql([true, false])
36
+ end
37
+
38
+ it "should initialize a prior_odds accessor" do
39
+ Variable.should have_an_initialization_accessor_for(:prior_odds)
40
+ end
41
+
42
+ it "should default the prior odds to the uniform set for the outcomes" do
43
+ v = Variable.new
44
+ v.prior_odds.should eql([0.5, 0.5])
45
+ v = Variable.new :outcomes => [:a, :b, :c]
46
+ v.prior_odds.should eql([1/3.0, 1/3.0, 1/3.0])
47
+ end
48
+
49
+ # =================
50
+ # = Equality (==) =
51
+ # =================
52
+ it "should be equal by name" do
53
+ v1 = Variable.new(:name => :name)
54
+ v2 = Variable.new(:name => :name)
55
+ v1.should ==(v2)
56
+ end
57
+
58
+ # =========
59
+ # = Infer =
60
+ # =========
61
+ context "when infering" do
62
+ it "should be able to infer from a variable" do
63
+ @v1 = Variable.new
64
+ Variable.infer(@v1).should eql(@v1)
65
+ end
66
+
67
+ it "should be able to infer from a hash" do
68
+ @hash = {:name => :name, :prior_odds => [0.4, 0.6]}
69
+ @v1 = Variable.new(@hash)
70
+ Variable.infer(@hash).should ==(@v1)
71
+ end
72
+
73
+ it "should be able to infer from a symbol" do
74
+ @symbol = :name
75
+ @v1 = Variable.new(:name => @symbol)
76
+ Variable.infer(@symbol).should ==(@v1)
77
+ end
78
+
79
+ it "should be able to infer from a string" do
80
+ @string = 'name'
81
+ @v1 = Variable.new(:name => @string)
82
+ Variable.infer(@string).should ==(@v1)
83
+ end
84
+
85
+ end
86
+
87
+ # ======
88
+ # = ID =
89
+ # ======
90
+ context "when ensuring a unique id" do
91
+ before do
92
+ @v = Variable.new
93
+ end
94
+
95
+ it "should have an id, a UUID" do
96
+ uuid_re = /^\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}$/
97
+ @v.id.should match(uuid_re)
98
+ end
99
+ end
100
+
101
+ end