activefacts 1.6.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +14 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +60 -0
  8. data/Rakefile +3 -80
  9. data/activefacts.gemspec +36 -0
  10. data/bin/afgen +4 -2
  11. data/bin/cql +5 -1
  12. data/lib/activefacts.rb +3 -12
  13. data/lib/activefacts/{vocabulary/query_evaluator.rb → query/evaluator.rb} +0 -0
  14. data/lib/activefacts/version.rb +2 -2
  15. metadata +48 -296
  16. data/History.txt +0 -4
  17. data/LICENSE +0 -19
  18. data/Manifest.txt +0 -165
  19. data/README.rdoc +0 -81
  20. data/css/offline.css +0 -3
  21. data/css/orm2.css +0 -124
  22. data/css/print.css +0 -8
  23. data/css/style-print.css +0 -357
  24. data/css/style.css +0 -387
  25. data/download.html +0 -110
  26. data/examples/CQL/Address.cql +0 -44
  27. data/examples/CQL/Blog.cql +0 -54
  28. data/examples/CQL/CompanyDirectorEmployee.cql +0 -56
  29. data/examples/CQL/Death.cql +0 -17
  30. data/examples/CQL/Diplomacy.cql +0 -48
  31. data/examples/CQL/Genealogy.cql +0 -98
  32. data/examples/CQL/Insurance.cql +0 -320
  33. data/examples/CQL/Marriage.cql +0 -18
  34. data/examples/CQL/Metamodel.cql +0 -493
  35. data/examples/CQL/Monogamy.cql +0 -24
  36. data/examples/CQL/MultiInheritance.cql +0 -22
  37. data/examples/CQL/NonRoleId.cql +0 -14
  38. data/examples/CQL/OddIdentifier.cql +0 -18
  39. data/examples/CQL/OilSupply.cql +0 -53
  40. data/examples/CQL/OneToOnes.cql +0 -17
  41. data/examples/CQL/Orienteering.cql +0 -111
  42. data/examples/CQL/PersonPlaysGame.cql +0 -18
  43. data/examples/CQL/RedundantDependency.cql +0 -34
  44. data/examples/CQL/SchoolActivities.cql +0 -33
  45. data/examples/CQL/SeparateSubtype.cql +0 -30
  46. data/examples/CQL/ServiceDirector.cql +0 -276
  47. data/examples/CQL/SimplestUnary.cql +0 -12
  48. data/examples/CQL/Supervision.cql +0 -34
  49. data/examples/CQL/WaiterTips.cql +0 -33
  50. data/examples/CQL/Warehousing.cql +0 -101
  51. data/examples/CQL/WindowInRoomInBldg.cql +0 -28
  52. data/examples/CQL/unit.cql +0 -474
  53. data/examples/index.html +0 -420
  54. data/examples/intro.html +0 -327
  55. data/examples/local.css +0 -24
  56. data/index.html +0 -111
  57. data/lib/activefacts/cql.rb +0 -35
  58. data/lib/activefacts/cql/CQLParser.treetop +0 -158
  59. data/lib/activefacts/cql/Context.treetop +0 -48
  60. data/lib/activefacts/cql/Expressions.treetop +0 -67
  61. data/lib/activefacts/cql/FactTypes.treetop +0 -358
  62. data/lib/activefacts/cql/Language/English.treetop +0 -315
  63. data/lib/activefacts/cql/LexicalRules.treetop +0 -253
  64. data/lib/activefacts/cql/ObjectTypes.treetop +0 -210
  65. data/lib/activefacts/cql/Rakefile +0 -14
  66. data/lib/activefacts/cql/Terms.treetop +0 -183
  67. data/lib/activefacts/cql/ValueTypes.treetop +0 -202
  68. data/lib/activefacts/cql/compiler.rb +0 -156
  69. data/lib/activefacts/cql/compiler/clause.rb +0 -1137
  70. data/lib/activefacts/cql/compiler/constraint.rb +0 -581
  71. data/lib/activefacts/cql/compiler/entity_type.rb +0 -457
  72. data/lib/activefacts/cql/compiler/expression.rb +0 -443
  73. data/lib/activefacts/cql/compiler/fact.rb +0 -390
  74. data/lib/activefacts/cql/compiler/fact_type.rb +0 -421
  75. data/lib/activefacts/cql/compiler/query.rb +0 -106
  76. data/lib/activefacts/cql/compiler/shared.rb +0 -161
  77. data/lib/activefacts/cql/compiler/value_type.rb +0 -174
  78. data/lib/activefacts/cql/nodes.rb +0 -49
  79. data/lib/activefacts/cql/parser.rb +0 -241
  80. data/lib/activefacts/dependency_analyser.rb +0 -182
  81. data/lib/activefacts/generate/absorption.rb +0 -70
  82. data/lib/activefacts/generate/composition.rb +0 -118
  83. data/lib/activefacts/generate/cql.rb +0 -714
  84. data/lib/activefacts/generate/dm.rb +0 -279
  85. data/lib/activefacts/generate/help.rb +0 -64
  86. data/lib/activefacts/generate/helpers/inject.rb +0 -16
  87. data/lib/activefacts/generate/helpers/oo.rb +0 -162
  88. data/lib/activefacts/generate/helpers/ordered.rb +0 -605
  89. data/lib/activefacts/generate/helpers/rails.rb +0 -57
  90. data/lib/activefacts/generate/html/glossary.rb +0 -461
  91. data/lib/activefacts/generate/json.rb +0 -337
  92. data/lib/activefacts/generate/null.rb +0 -32
  93. data/lib/activefacts/generate/rails/models.rb +0 -246
  94. data/lib/activefacts/generate/rails/schema.rb +0 -216
  95. data/lib/activefacts/generate/records.rb +0 -46
  96. data/lib/activefacts/generate/ruby.rb +0 -133
  97. data/lib/activefacts/generate/sql/mysql.rb +0 -280
  98. data/lib/activefacts/generate/sql/server.rb +0 -273
  99. data/lib/activefacts/generate/stats.rb +0 -69
  100. data/lib/activefacts/generate/text.rb +0 -27
  101. data/lib/activefacts/generate/topics.rb +0 -265
  102. data/lib/activefacts/generate/traits/datavault.rb +0 -241
  103. data/lib/activefacts/generate/traits/oo.rb +0 -73
  104. data/lib/activefacts/generate/traits/ordered.rb +0 -33
  105. data/lib/activefacts/generate/traits/ruby.rb +0 -210
  106. data/lib/activefacts/generate/transform/datavault.rb +0 -266
  107. data/lib/activefacts/generate/transform/surrogate.rb +0 -214
  108. data/lib/activefacts/generate/version.rb +0 -26
  109. data/lib/activefacts/input/cql.rb +0 -43
  110. data/lib/activefacts/input/orm.rb +0 -1636
  111. data/lib/activefacts/mapping/rails.rb +0 -132
  112. data/lib/activefacts/persistence.rb +0 -15
  113. data/lib/activefacts/persistence/columns.rb +0 -446
  114. data/lib/activefacts/persistence/foreignkey.rb +0 -187
  115. data/lib/activefacts/persistence/index.rb +0 -240
  116. data/lib/activefacts/persistence/object_type.rb +0 -198
  117. data/lib/activefacts/persistence/reference.rb +0 -434
  118. data/lib/activefacts/persistence/tables.rb +0 -380
  119. data/lib/activefacts/registry.rb +0 -11
  120. data/lib/activefacts/support.rb +0 -132
  121. data/lib/activefacts/vocabulary.rb +0 -9
  122. data/lib/activefacts/vocabulary/extensions.rb +0 -1348
  123. data/lib/activefacts/vocabulary/metamodel.rb +0 -570
  124. data/lib/activefacts/vocabulary/verbaliser.rb +0 -804
  125. data/script/txt2html +0 -71
  126. data/spec/absorption_spec.rb +0 -95
  127. data/spec/cql/comparison_spec.rb +0 -89
  128. data/spec/cql/context_spec.rb +0 -94
  129. data/spec/cql/contractions_spec.rb +0 -224
  130. data/spec/cql/deontic_spec.rb +0 -88
  131. data/spec/cql/entity_type_spec.rb +0 -320
  132. data/spec/cql/expressions_spec.rb +0 -66
  133. data/spec/cql/fact_type_matching_spec.rb +0 -338
  134. data/spec/cql/french_spec.rb +0 -21
  135. data/spec/cql/parser/bad_literals_spec.rb +0 -86
  136. data/spec/cql/parser/constraints_spec.rb +0 -19
  137. data/spec/cql/parser/entity_types_spec.rb +0 -106
  138. data/spec/cql/parser/expressions_spec.rb +0 -199
  139. data/spec/cql/parser/fact_types_spec.rb +0 -44
  140. data/spec/cql/parser/literals_spec.rb +0 -312
  141. data/spec/cql/parser/pragmas_spec.rb +0 -89
  142. data/spec/cql/parser/value_types_spec.rb +0 -42
  143. data/spec/cql/role_matching_spec.rb +0 -148
  144. data/spec/cql/samples_spec.rb +0 -244
  145. data/spec/cql_cql_spec.rb +0 -73
  146. data/spec/cql_dm_spec.rb +0 -136
  147. data/spec/cql_mysql_spec.rb +0 -69
  148. data/spec/cql_parse_spec.rb +0 -34
  149. data/spec/cql_ruby_spec.rb +0 -73
  150. data/spec/cql_sql_spec.rb +0 -72
  151. data/spec/cql_symbol_tables_spec.rb +0 -261
  152. data/spec/cqldump_spec.rb +0 -170
  153. data/spec/helpers/array_matcher.rb +0 -23
  154. data/spec/helpers/ctrl_c_support.rb +0 -52
  155. data/spec/helpers/diff_matcher.rb +0 -39
  156. data/spec/helpers/file_matcher.rb +0 -34
  157. data/spec/helpers/parse_to_ast_matcher.rb +0 -80
  158. data/spec/helpers/string_matcher.rb +0 -30
  159. data/spec/helpers/test_parser.rb +0 -15
  160. data/spec/norma_cql_spec.rb +0 -66
  161. data/spec/norma_ruby_spec.rb +0 -62
  162. data/spec/norma_ruby_sql_spec.rb +0 -107
  163. data/spec/norma_sql_spec.rb +0 -57
  164. data/spec/norma_tables_spec.rb +0 -95
  165. data/spec/ruby_api_spec.rb +0 -23
  166. data/spec/spec_helper.rb +0 -35
  167. data/spec/transform_surrogate_spec.rb +0 -59
  168. data/status.html +0 -138
  169. data/why.html +0 -60
@@ -1,71 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- load File.dirname(__FILE__) + "/../Rakefile"
4
- require 'rubyforge'
5
- require 'redcloth'
6
- require 'syntax/convertors/html'
7
- require 'erb'
8
-
9
- download = "http://rubyforge.org/projects/#{$hoe.rubyforge_name}"
10
- version = $hoe.version
11
-
12
- def rubyforge_project_id
13
- RubyForge.new.configure.autoconfig["group_ids"][$hoe.rubyforge_name]
14
- end
15
-
16
- class Fixnum
17
- def ordinal
18
- # teens
19
- return 'th' if (10..19).include?(self % 100)
20
- # others
21
- case self % 10
22
- when 1: return 'st'
23
- when 2: return 'nd'
24
- when 3: return 'rd'
25
- else return 'th'
26
- end
27
- end
28
- end
29
-
30
- class Time
31
- def pretty
32
- return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
33
- end
34
- end
35
-
36
- def convert_syntax(syntax, source)
37
- return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
38
- end
39
-
40
- if ARGV.length >= 1
41
- src, template = ARGV
42
- template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
43
- else
44
- puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
45
- exit!
46
- end
47
-
48
- template = ERB.new(File.open(template).read)
49
-
50
- title = nil
51
- body = nil
52
- File.open(src) do |fsrc|
53
- title_text = fsrc.readline
54
- body_text_template = fsrc.read
55
- body_text = ERB.new(body_text_template).result(binding)
56
- syntax_items = []
57
- body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
58
- ident = syntax_items.length
59
- element, syntax, source = $1, $2, $3
60
- syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
61
- "syntax-temp-#{ident}"
62
- }
63
- title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
64
- body = RedCloth.new(body_text).to_html
65
- body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
66
- end
67
- stat = File.stat(src)
68
- created = stat.ctime
69
- modified = stat.mtime
70
-
71
- $stdout << template.result(binding)
@@ -1,95 +0,0 @@
1
- #
2
- # ActiveFacts tests: Test the relational absorption by compiling CQL fragments.
3
- # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
- #
5
-
6
- require 'spec_helper'
7
- require 'activefacts/support'
8
- require 'activefacts/api/support'
9
- require 'activefacts/input/cql'
10
- require 'activefacts/persistence'
11
-
12
- describe "Absorption" do
13
- AT_Prologue = %Q{
14
- vocabulary Test;
15
- DateTime is written as DateAndTime();
16
- Month is written as VariableLengthText(3);
17
- Season is written as VariableLengthText(6);
18
- PartyID is written as AutoCounter();
19
- ClaimID is written as AutoCounter();
20
- }
21
- AT_Claim = %Q{
22
- Claim is identified by ClaimID where
23
- Claim has exactly one ClaimID,
24
- ClaimID is of at most one Claim;
25
- Claim was reported on one DateTime;
26
- }
27
- AT_Incident = %Q{
28
- Incident is identified by Claim where
29
- Claim concerns at most one Incident,
30
- Incident is of exactly one Claim;
31
- }
32
- AT_Party = %Q{
33
- Party is identified by PartyID where
34
- Party has exactly one PartyID,
35
- PartyID is of at most one Party;
36
- }
37
- AT_Person = %Q{
38
- Person is a kind of Party;
39
- }
40
-
41
- Tests = [
42
- { :should => "inject a value column into the table for an independent ValueType",
43
- :cql => %Q{
44
- #{AT_Prologue}
45
- Month is in exactly one Season;
46
- },
47
- :tables => { "Month" => [["Month", "Value"], ["Season"]] }
48
- },
49
-
50
- { :should => "absorb a one-to-one along the identification path",
51
- :cql => %Q{
52
- #{AT_Prologue} #{AT_Claim} #{AT_Incident}
53
- Incident relates to loss on exactly one DateTime;
54
- },
55
- :tables => { "Claim" => [%w{Claim ID}, %w{Date Time}, %w{Incident Date Time}]}
56
- },
57
-
58
- { :should => "absorb an objectified binary with single-role UC",
59
- :cql => %Q{
60
- #{AT_Prologue} #{AT_Claim} #{AT_Party} #{AT_Person}
61
- Lodgement is where
62
- Claim was lodged by at most one Person;
63
- Lodgement was made at at most one DateTime;
64
- Person has exactly one birth-DateTime;
65
- },
66
- :tables => {
67
- "Claim" => [%w{Claim ID}, %w{Date Time}, %w{Lodgement Date Time}, %w{Lodgement Person ID}],
68
- "Party" => [%w{Party ID}, %w{Person Birth Date Time}]
69
- }
70
- },
71
-
72
- ]
73
-
74
- Tests.each do |test|
75
- should = test[:should]
76
- cql = test[:cql]
77
- expected_tables = test[:tables]
78
- it "should #{should}" do
79
- @compiler = ActiveFacts::CQL::Compiler.new(should)
80
- @vocabulary = @compiler.compile(cql)
81
-
82
- # puts cql
83
-
84
- # Ensure that the same tables were generated:
85
- tables = @vocabulary.tables.sort_by(&:name)
86
- tables.map(&:name).should == expected_tables.keys.sort
87
-
88
- # Ensure that the same column descriptions were generated:
89
- tables.each do |table|
90
- column_descriptions = table.columns.map{|col| col.name(nil) }.sort
91
- column_descriptions.should == expected_tables[table.name].map{|c| Array(c) }.sort
92
- end
93
- end
94
- end
95
- end
@@ -1,89 +0,0 @@
1
- #
2
- # ActiveFacts CQL Comparison Fact Type tests
3
- # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
4
- #
5
-
6
- require 'rspec/expectations'
7
-
8
- require 'activefacts/support'
9
- require 'activefacts/api/support'
10
- require 'activefacts/cql/compiler'
11
- require File.dirname(__FILE__) + '/../helpers/compile_helpers'
12
-
13
- describe "When matching a reading with an existing fact type" do
14
- before :each do
15
- extend CompileHelpers
16
-
17
- prefix = %q{
18
- vocabulary Tests;
19
- Name is written as String;
20
- year/years converts to 365.25 day;
21
- Age is written as Integer year;
22
- Person is identified by its Name;
23
- Person is of Age;
24
-
25
- // Company is identified by its Name;
26
- // Directorship is where Person directs Company;
27
- }
28
- @compiler = ActiveFacts::CQL::Compiler.new('Test')
29
- @compiler.compile(prefix)
30
- @constellation = @compiler.vocabulary.constellation
31
-
32
- baseline
33
- end
34
-
35
- describe "equality comparisons" do
36
- before :each do
37
- #debug_enable("binding"); debug_enable("matching"); debug_enable("matching_fails"); debug_enable("parse")
38
- end
39
- after :each do
40
- #debug_disable("binding"); debug_disable("matching"); debug_disable("matching_fails"); debug_disable("parse")
41
- end
42
-
43
- def value_should_match value, lit, unit = nil
44
- value.should_not be_nil
45
- value.literal.should == lit.to_s
46
- (!!value.is_literal_string).should == lit.is_a?(String)
47
- if unit
48
- value.unit.should_not be_nil
49
- value.unit.name.should == unit
50
- else
51
- value.unit.should be_nil
52
- end
53
- end
54
-
55
- def one_query_with_value v, unit = nil
56
- queries.size.should == 1
57
- (jss = steps).size.should == 2
58
- (jns = variables).size.should == 3
59
- integer_node = jns.detect{|jn| jn.object_type.name == 'Integer'}
60
- integer_node.should_not be_nil
61
- value_should_match integer_node.value, v, unit
62
- # pending should test content of the steps
63
- end
64
-
65
- it "should create a comparison fact type" do
66
- compile %q{Person is old where Person is of Age >= 60 years; }
67
- (new_fact_types = fact_types).size.should == 2
68
-
69
- is_old_ft = new_fact_types.detect{|ft| ft.all_reading.detect{|r| r.text =~ /is old/} }
70
- (is_old_ft.all_reading.map{ |r| r.expand }*', ').should == "Person is old"
71
-
72
- comparison_ft = (new_fact_types - [is_old_ft])[0]
73
- (comparison_ft.all_reading.map{ |r| r.expand }*', ').should == "Boolean = Age >= Integer"
74
-
75
- one_query_with_value 60, 'year'
76
- end
77
-
78
- it "should create a comparison fact type twice without duplication"
79
-
80
- it "should parse a query and comparison fact type" do
81
- compile %q{Person is of Age >= 60 years? }
82
- (new_fact_types = fact_types).size.should == 1
83
- (readings = new_fact_types[0].all_reading).size.should == 1
84
- readings.single.text.should == '{0} = {1} >= {2}'
85
-
86
- one_query_with_value 60, 'year'
87
- end
88
- end
89
- end
@@ -1,94 +0,0 @@
1
- #
2
- # ActiveFacts CQL Business Context Note tests
3
- # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
4
- #
5
-
6
- require 'activefacts/support'
7
- require 'activefacts/api/support'
8
- require 'activefacts/cql/compiler'
9
-
10
- describe "Business Context Notes" do
11
- # (according_to people ',')? (because / as_opposed_to / so_that / to_avoid) discussion (',' as_agreed_by)? s
12
- ContextNotePrefix = %q{
13
- vocabulary Test;
14
- Person is written as Person;
15
- Person is employed;
16
- Person is unemployed;
17
- Person is a bad credit risk;
18
- Person is good credit risk;
19
- Bar is written as Bar;
20
- Baz is written as Baz;
21
- }
22
- Notes = [
23
- # Constraints:
24
- [ 'each Person occurs one time in Person is employed, Person is unemployed (because it can be no other way!);',
25
- 1, 'because'
26
- ],
27
- [ 'each Person occurs one time in Person is employed, Person is unemployed (as opposed to blah!);',
28
- 1, 'as_opposed_to'
29
- ],
30
- [ 'for each Person at least one of these holds: Person is employed, Person is a bad credit risk (so that blah);',
31
- 1, 'so_that'
32
- ],
33
- [ 'Person is good credit risk only if Person is employed (to avoid lending to people who can\'t repay);',
34
- 1, 'to_avoid'
35
- ],
36
- [ 'Person is good credit risk if and only if Person is employed (to avoid lending to people who can\'t repay);',
37
- 1, 'to_avoid'
38
- ],
39
- [ 'Person is good credit risk if and only if Person is employed (to avoid lending to people who can\'t repay, as agreed by Jim);',
40
- 1, 'to_avoid', nil, ['Jim']
41
- ],
42
- # Entity and Fact types
43
- # Entity and Fact types
44
- [ 'Foo is identified by Bar [independent] where Foo has one(to avoid fuckups) Bar (so that we have an id);',
45
- 1, 'so_that'
46
- ],
47
- [ 'Baz has one Bar (so that we have an id), Bar is of one Baz (because we need that);',
48
- 2
49
- ],
50
- # REVISIT: No context notes on quantifiers yet
51
- # As agreed by:
52
- [ 'for each Person at least one of these holds: Person is employed, Person is a bad credit risk (so that blah, as agreed by Jim);',
53
- 1, 'so_that', nil, ['Jim']
54
- ],
55
- # REVISIT: Populate an "as agreed by" with a date
56
- [ 'for each Person at least one of these holds: Person is employed, Person is a bad credit risk (so that blah, as agreed on 10-04-10 by Jim);',
57
- 1, 'so_that', nil, ['Jim'], '10-04-10'
58
- ],
59
- # According to:
60
- [ 'for each Person at least one of these holds: Person is employed, Person is a bad credit risk (according to jim, so that blah);',
61
- 1, 'so_that', ['jim']
62
- ],
63
- ]
64
-
65
- before :each do
66
- @compiler = ActiveFacts::CQL::Compiler.new('Test')
67
- end
68
-
69
- Notes.each do |c|
70
- source, count, kind, according_to, agreed_by, agreed_date = *c
71
- it "should parse #{source.inspect}" do
72
-
73
- result =
74
- begin
75
- @compiler.compile(ContextNotePrefix+source)
76
- rescue => e
77
- puts "#{e}:\n\t#{e.backtrace*"\n\t"}"
78
- end
79
- puts @compiler.failure_reason unless result
80
- result.should_not be_nil
81
- constellation = @compiler.vocabulary.constellation
82
-
83
- # constellation.ContextNote.each{|k,cn| puts "#{k.inspect} => #{cn.inspect}" }
84
- constellation.ContextNote.size.should == (count || 1)
85
- context_note = constellation.ContextNote.values[0]
86
- context_note.context_note_kind.should == kind if kind
87
- context_note.all_context_according_to.map{|cat| cat.agent.agent_name }.sort.should == according_to if according_to
88
- # context_note.discussion.should == discussion if discussion
89
- context_note.agreement.should_not be_nil if agreed_by || agreed_date
90
- context_note.agreement.all_context_agreed_by.map{|cab| cab.agent.agent_name}.sort.should == agreed_by if agreed_by
91
- context_note.agreement.date.should == Date.parse(agreed_date) if agreed_date
92
- end
93
- end
94
- end
@@ -1,224 +0,0 @@
1
- #
2
- # ActiveFacts CQL Fact Type matching tests - contractions.
3
- # Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
4
- #
5
- # Contractions are where a fact type clause is followed by another (with
6
- # some conjunction except for comparisons) with one player *implicit* in
7
- # the following clause.
8
- #
9
- # Right contraction elides the repetition of the right-most player,
10
- # and left contraction elides the left-most player.
11
- #
12
- # So, using the notation "A rel B" for binaries,
13
- # "A relA B relA C" for ternaries, and "C prop" for properties,
14
- # we can write equivalences as follows.
15
- #
16
- # Note 1: Terms may be more than one word.
17
- # Note 2: For any "A rel B", the example also applies to a ternary or
18
- # higher, as appropriate.
19
-
20
- =begin
21
- Right contractions with 'and':
22
- A rel B and B prop
23
- -> A rel B who/that prop
24
- E.g. Person pats Cat that is asleep
25
-
26
- A rel B and B rel2 C
27
- -> A rel B who/that rel2 C
28
- E.g. Person pats Cat that is lying on Mat
29
-
30
- A rel B and B rel2A C rel2A D
31
- -> A rel B who/that rel2A C rel2B D
32
- E.g. Person pats Cat that ate Food at Time
33
-
34
- A rel B and B > C
35
- -> A rel B > C
36
- E.g. Person is of Age >= 21
37
-
38
- A > B and B rel C
39
- -> A > B rel C
40
- E.g. 21 > Age of Person
41
-
42
- Right contractions with ',':
43
- A rel B, B rel2 C
44
- -> A rel B who/that rel2 C
45
-
46
- A rel B, B prop
47
- -> A rel B who/that prop
48
-
49
- A rel B, B > C
50
- -> A rel B > C
51
-
52
- A > B, B rel C
53
- -> A > B rel C
54
-
55
- Left contractions with 'and':
56
- A rel B and A rel2 C
57
- -> A rel B and rel2 C
58
- E.g. Boy seduces Girl and is drunk
59
-
60
- A rel B and A prop
61
- -> A rel B and prop
62
-
63
- A rel B and A > C
64
- -> A rel B and > C
65
-
66
- Left contractions with 'or':
67
- A rel B or A rel2 C
68
- -> A rel B or rel2 C
69
-
70
- A rel B or A prop
71
- -> A rel B or prop
72
-
73
- A rel B or A > C
74
- -> A rel B or > C
75
-
76
- A > B or A rel C
77
- -> A > B or rel C
78
-
79
- Double contractions (not supported in CQL yet):
80
- A rel B and A rel2 B
81
- -> A rel B and rel2
82
- E.g. Person came to Party and was invited to
83
-
84
- Extended contractions (not supported in CQL yet) (note the ambiguity - if allowed, the first takes precedence!):
85
- A rel B and B rel2 C and B prop
86
- -> A rel B that rel2 C and prop
87
- E.g. LazyDogOwner is a Person who owns Dog that barks and Dog is lazy.
88
-
89
- A rel B and B rel2 C and A prop
90
- -> A rel B that rel2 C and prop
91
- E.g. LazyDogOwner is a Person who owns Dog that barks and Person is lazy.
92
-
93
- And/or resolution:
94
- A rel B and B rel2 C or A rel3 D
95
- A rel B and B rel2 C or B rel3 D -> Logical, A must rel B but B can carry either rel
96
- A rel B and B rel2 C or C rel3 D -> Illogical form (mandates B rel2 C so 'or' is meaningless)
97
-
98
- Ambiguous, disallowed:
99
- A > 2 + B > C
100
-
101
- Comments from Matt on contraction and verbalisation:
102
-
103
- I have two types of list phrases which I classify as 'header' and 'inline'.
104
- And and or are inline, the other four (negated and/or, positive or negative
105
- xor) all use header forms. There is also a header form of negation (it is not
106
- true that...). The header forms (all of the following must be true: etc) can
107
- introduce vars in the starting context, but not those introduced by previous
108
- elements in the list.
109
-
110
- You'll likely need something similar, though, on nested expressions. You also
111
- have to decide where your implicit existential placement is if you use the
112
- same var in multiple branches or under negation. Lots of fun stuff.
113
-
114
- =end
115
-
116
-
117
- require 'rspec/expectations'
118
-
119
- require 'activefacts/support'
120
- require 'activefacts/api/support'
121
- require 'activefacts/cql/compiler'
122
- require File.dirname(__FILE__) + '/../helpers/compile_helpers' # Can't see how to include/extend these methods correctly
123
-
124
- describe "When compiling a query, " do
125
- before :each do
126
- extend CompileHelpers
127
-
128
- prefix = %q{
129
- vocabulary Tests;
130
- Boy is written as String;
131
- Girl is written as Integer;
132
- Age is written as Integer;
133
- Boy is of Age;
134
- Boy is going out with Girl, Girl is going out with Boy;
135
- }
136
- @compiler = ActiveFacts::CQL::Compiler.new('Test')
137
- @compiler.compile(prefix)
138
- @constellation = @compiler.vocabulary.constellation
139
-
140
- baseline
141
-
142
- def self.compile string
143
- lambda {
144
- @compiler.compile string
145
- }.should_not raise_error
146
- end
147
- end
148
-
149
- shared_examples_for "single contractions" do
150
- it "should produce one fact type" do
151
- (new_fact_types = fact_types).size.should == 1
152
- end
153
- it "the fact type should have one reading" do
154
- fact_type = fact_types[0]
155
- fact_type.all_reading.size.should == 1
156
- end
157
- it "the fact type should have no presence constraints" do
158
- fact_type = fact_types[0]
159
- (pcs = fact_pcs(fact_type)).size.should == 0
160
- end
161
- it "should produce one query" do
162
- fact_type = fact_types[0]
163
- query = derivation(fact_type)
164
- end
165
- it "the query should have 3 variables" do
166
- fact_type = fact_types[0]
167
- query = derivation(fact_type)
168
- variables = query.all_variable.to_a
169
- variables.size.should == 3
170
- end
171
- it "the query should have 2 steps" do
172
- fact_type = fact_types[0]
173
- query = derivation(fact_type)
174
- steps = query.all_step.to_a
175
- steps.size.should == 2
176
- end
177
-
178
- it "and should project the fact type roles from the query" do
179
- skip "Plays are not yet projected" do
180
- query = derivation(fact_type)
181
- queries = fact_type.all_role.map{|r| r.all_play.map{|play| play.query}}.flatten.uniq
182
- queries.size == 1
183
- queries.should == [query]
184
- end
185
- end
186
- end
187
-
188
- describe "right contractions having" do
189
- describe "a single contraction using 'who'" do
190
- before :each do
191
- compile %q{Boy is relevant where Girl is going out with Boy who is of Age; }
192
- end
193
-
194
- it_should_behave_like "single contractions"
195
- end
196
-
197
- describe "a single contraction using 'that'" do
198
- before :each do
199
- compile %q{Boy is relevant where Girl is going out with Boy that is of Age; }
200
- end
201
-
202
- it_should_behave_like "single contractions"
203
- end
204
- end
205
-
206
- describe "left contractions having" do
207
- describe "a single contraction" do
208
- before :each do
209
- compile %q{Boy is relevant where Boy is of Age and is going out with Girl; }
210
- end
211
-
212
- it_should_behave_like "single contractions"
213
- end
214
- end
215
- end
216
-
217
- =begin
218
- Examples on the Blog model:
219
-
220
- Post is nice where Post was written by Author and belongs to Topic and includes Ordinal paragraph;
221
- Post is nice where Post was written by Author and belongs to Topic or Post includes Ordinal paragraph or has Post Id;
222
- Post is nice where Post was written by Author and belongs to Topic or includes Ordinal paragraph;
223
- Post is nice where Post was written by Author and belongs to Topic or Post includes Ordinal paragraph or has Post Id;
224
- =end