activefacts 0.8.16 → 0.8.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +15 -0
  2. data/Manifest.txt +10 -4
  3. data/bin/afgen +26 -20
  4. data/bin/cql +1 -1
  5. data/css/orm2.css +89 -9
  6. data/examples/CQL/CompanyDirectorEmployee.cql +4 -4
  7. data/examples/CQL/Genealogy.cql +5 -5
  8. data/examples/CQL/Metamodel.cql +121 -91
  9. data/examples/CQL/MonthInSeason.cql +2 -6
  10. data/examples/CQL/SeparateSubtype.cql +11 -9
  11. data/examples/CQL/ServiceDirector.cql +21 -33
  12. data/examples/CQL/Supervision.cql +0 -3
  13. data/examples/CQL/WindowInRoomInBldg.cql +10 -4
  14. data/examples/CQL/unit.cql +1 -1
  15. data/lib/activefacts.rb +1 -0
  16. data/lib/activefacts/cql/CQLParser.treetop +5 -1
  17. data/lib/activefacts/cql/Context.treetop +2 -7
  18. data/lib/activefacts/cql/Expressions.treetop +2 -2
  19. data/lib/activefacts/cql/FactTypes.treetop +37 -31
  20. data/lib/activefacts/cql/Language/English.treetop +21 -4
  21. data/lib/activefacts/cql/LexicalRules.treetop +59 -1
  22. data/lib/activefacts/cql/ObjectTypes.treetop +22 -12
  23. data/lib/activefacts/cql/Terms.treetop +13 -9
  24. data/lib/activefacts/cql/ValueTypes.treetop +30 -11
  25. data/lib/activefacts/cql/compiler.rb +34 -5
  26. data/lib/activefacts/cql/compiler/clause.rb +207 -116
  27. data/lib/activefacts/cql/compiler/constraint.rb +129 -105
  28. data/lib/activefacts/cql/compiler/entity_type.rb +49 -27
  29. data/lib/activefacts/cql/compiler/expression.rb +71 -42
  30. data/lib/activefacts/cql/compiler/fact.rb +70 -64
  31. data/lib/activefacts/cql/compiler/fact_type.rb +108 -57
  32. data/lib/activefacts/cql/compiler/query.rb +178 -0
  33. data/lib/activefacts/cql/compiler/shared.rb +13 -12
  34. data/lib/activefacts/cql/compiler/value_type.rb +10 -4
  35. data/lib/activefacts/cql/nodes.rb +1 -1
  36. data/lib/activefacts/cql/parser.rb +6 -2
  37. data/lib/activefacts/generate/absorption.rb +6 -3
  38. data/lib/activefacts/generate/cql.rb +140 -84
  39. data/lib/activefacts/generate/dm.rb +12 -6
  40. data/lib/activefacts/generate/help.rb +25 -6
  41. data/lib/activefacts/generate/helpers/oo.rb +195 -0
  42. data/lib/activefacts/generate/helpers/ordered.rb +589 -0
  43. data/lib/activefacts/generate/helpers/rails.rb +57 -0
  44. data/lib/activefacts/generate/html/glossary.rb +274 -54
  45. data/lib/activefacts/generate/json.rb +25 -22
  46. data/lib/activefacts/generate/null.rb +1 -0
  47. data/lib/activefacts/generate/rails/models.rb +244 -0
  48. data/lib/activefacts/generate/rails/schema.rb +185 -0
  49. data/lib/activefacts/generate/records.rb +1 -0
  50. data/lib/activefacts/generate/ruby.rb +51 -30
  51. data/lib/activefacts/generate/sql/mysql.rb +5 -3
  52. data/lib/activefacts/generate/sql/server.rb +8 -4
  53. data/lib/activefacts/generate/text.rb +1 -0
  54. data/lib/activefacts/generate/transform/surrogate.rb +209 -0
  55. data/lib/activefacts/generate/version.rb +1 -0
  56. data/lib/activefacts/input/orm.rb +234 -181
  57. data/lib/activefacts/mapping/rails.rb +122 -0
  58. data/lib/activefacts/persistence/columns.rb +34 -18
  59. data/lib/activefacts/persistence/foreignkey.rb +129 -71
  60. data/lib/activefacts/persistence/index.rb +42 -12
  61. data/lib/activefacts/persistence/reference.rb +37 -23
  62. data/lib/activefacts/persistence/tables.rb +53 -19
  63. data/lib/activefacts/registry.rb +11 -0
  64. data/lib/activefacts/support.rb +28 -10
  65. data/lib/activefacts/version.rb +1 -1
  66. data/lib/activefacts/vocabulary/extensions.rb +246 -117
  67. data/lib/activefacts/vocabulary/metamodel.rb +105 -65
  68. data/lib/activefacts/vocabulary/verbaliser.rb +226 -194
  69. data/spec/absorption_spec.rb +1 -0
  70. data/spec/cql/comparison_spec.rb +8 -8
  71. data/spec/cql/contractions_spec.rb +16 -43
  72. data/spec/cql/entity_type_spec.rb +2 -1
  73. data/spec/cql/expressions_spec.rb +2 -2
  74. data/spec/cql/fact_type_matching_spec.rb +4 -1
  75. data/spec/cql/parser/bad_literals_spec.rb +30 -30
  76. data/spec/cql/parser/entity_types_spec.rb +6 -6
  77. data/spec/cql/parser/expressions_spec.rb +25 -19
  78. data/spec/cql/samples_spec.rb +5 -4
  79. data/spec/cql_cql_spec.rb +2 -1
  80. data/spec/cql_dm_spec.rb +4 -0
  81. data/spec/cql_mysql_spec.rb +4 -0
  82. data/spec/cql_parse_spec.rb +2 -0
  83. data/spec/cql_ruby_spec.rb +4 -0
  84. data/spec/cql_sql_spec.rb +4 -0
  85. data/spec/cqldump_spec.rb +7 -4
  86. data/spec/helpers/parse_to_ast_matcher.rb +7 -3
  87. data/spec/helpers/test_parser.rb +2 -0
  88. data/spec/norma_cql_spec.rb +5 -2
  89. data/spec/norma_ruby_spec.rb +4 -1
  90. data/spec/norma_ruby_sql_spec.rb +4 -1
  91. data/spec/norma_sql_spec.rb +4 -1
  92. data/spec/norma_tables_spec.rb +2 -2
  93. data/spec/ruby_api_spec.rb +1 -1
  94. data/spec/spec_helper.rb +2 -0
  95. data/spec/transform_surrogate_spec.rb +59 -0
  96. metadata +70 -60
  97. data/TODO +0 -308
  98. data/lib/activefacts/cql/compiler/join.rb +0 -162
  99. data/lib/activefacts/generate/oo.rb +0 -176
  100. data/lib/activefacts/generate/ordered.rb +0 -602
@@ -18,10 +18,6 @@ Occurrence is where
18
18
  /*
19
19
  * Fact Types
20
20
  */
21
- Month is in at most one Season;
21
+ Month is in at most one Season,
22
+ Season contains at least one Month;
22
23
 
23
- /*
24
- * Constraints:
25
- */
26
- each Season occurs at least one time in
27
- Month is in Season;
@@ -5,24 +5,26 @@ vocabulary SeparateSubtype;
5
5
  */
6
6
  Claim ID is written as Auto Counter;
7
7
  Date Time is written as Date Time;
8
- Driver Name is written as String;
8
+ Person Name is written as String;
9
9
 
10
10
  /*
11
11
  * Entity Types
12
12
  */
13
13
  Claim is identified by its ID;
14
14
 
15
- Driver is identified by its Name;
16
-
17
15
  Incident is identified by Claim where
18
- Claim concerns at most one Incident;
16
+ Claim concerns at most one Incident,
17
+ Incident resulted in one Claim;
19
18
  Incident occurred on at most one Date Time;
20
19
 
20
+ Person is identified by its Name;
21
+
21
22
  Vehicle Incident is a kind of Incident [separate];
23
+
24
+ Witness is a kind of Person;
25
+ Witness saw Incident,
26
+ Incident was seen by at most one Witness;
27
+
28
+ Driver is a kind of Person;
22
29
  Vehicle Incident occured while at most one Driver was in charge;
23
30
 
24
- /*
25
- * Constraints:
26
- */
27
- each Incident occurs one time in
28
- Claim concerns Incident;
@@ -5,13 +5,12 @@ vocabulary ServiceDirector;
5
5
  */
6
6
  Company Code is written as Char(5);
7
7
  Credential Nr is written as Signed Integer(32);
8
- DDMMYYYY is written as Date;
9
8
  Data Store Name is written as String(15);
9
+ Date is written as String;
10
+ Date Time is written as String;
10
11
  Email Address is written as String(50);
11
- HHMMSS is written as Time;
12
12
  Host System Name is written as String(15);
13
13
  IP is written as String(16);
14
- MDYHMS is written as Auto Time Stamp;
15
14
  Message Data is written as Blob(8000);
16
15
  Message Header is written as String(30);
17
16
  Monitor Id is written as Auto Counter;
@@ -32,6 +31,7 @@ Serial Number is written as String(20);
32
31
  Service Type [independent] is written as String(15);
33
32
  Subscription Nr is written as Signed Integer(32);
34
33
  Switch Id is written as Auto Counter;
34
+ Time is written as String;
35
35
  Transaction Nr is written as Unsigned Integer(32);
36
36
  Truck PCID is written as Unsigned Integer(32);
37
37
  User Name is written as String(20);
@@ -46,27 +46,19 @@ Company is client;
46
46
  Company is vendor;
47
47
 
48
48
  Credential is identified by its Nr;
49
+ Credential has at most one Expiration-Date;
49
50
  Credential has one Password;
50
51
  Credential has one User Name;
51
52
 
52
53
  Data Store is identified by its Name;
53
54
  Data Store requires at least one Credential;
54
55
  Data Store has one Friendly-Name;
55
- Data Store has at most one Heart- Beat Truck PCID;
56
+ Data Store has at most one HeartBeat-Truck PCID;
56
57
  Data Store has one Internal-Credential;
57
58
  Data Store is one Major-Version;
58
59
  Data Store is one Minor-Version;
59
60
  Data Store is one Revision-Version;
60
61
 
61
- Date Time YMDHMS is identified by MDYHMS where
62
- Date Time YMDHMS has one MDYHMS,
63
- MDYHMS is of at most one Date Time YMDHMS;
64
-
65
- DateYYMMDD is identified by DDMMYYYY where
66
- DateYYMMDD has one DDMMYYYY,
67
- DDMMYYYY is of at most one DateYYMMDD;
68
- Credential has at most one Expiration-DateYYMMDD;
69
-
70
62
  Duration is identified by Seconds where
71
63
  Duration has one Seconds,
72
64
  Seconds is of at most one Duration;
@@ -89,8 +81,8 @@ Monitor is owned by one Monitoring Application;
89
81
 
90
82
  Network is identified by its Nr;
91
83
  Company has at least one Origin-Network;
92
- Data Store has Tcp- Proxy Network,
93
- Tcp- Proxy Network is in at most one Data Store;
84
+ Data Store has TcpProxy-Network,
85
+ TcpProxy-Network is in at most one Data Store;
94
86
  Host System uses at least one Network,
95
87
  Network is used by at most one Host System;
96
88
  Network uses at most one Domain-Name;
@@ -102,7 +94,7 @@ Network is ip_single;
102
94
  Network is ip_subnet;
103
95
 
104
96
  Notification Level is identified by its Nr;
105
- Notification Level has one Initial- Delay Duration;
97
+ Notification Level has one InitialDelay-Duration;
106
98
  Notification Level has one Repeat-Duration;
107
99
 
108
100
  Notification Type is independent identified by its Name;
@@ -110,12 +102,13 @@ Notification Type is independent identified by its Name;
110
102
  Provider Type is identified by its Id;
111
103
 
112
104
  Recurring Schedule is identified by its Id;
113
- Monitor has All- Exclusion Recurring Schedule,
114
- All- Exclusion Recurring Schedule applies to at most one Monitor;
115
- Monitor (as IntegratingMonitor) has Integration- Exclusion Recurring Schedule; // Avoid ambiguity; this is a new fact type
116
- Monitor (as IntegratingMonitor) has Integration- Exclusion Recurring Schedule,
117
- Integration- Exclusion Recurring Schedule applies to at most one IntegratingMonitor;
105
+ Monitor has AllExclusion-Recurring Schedule,
106
+ AllExclusion-Recurring Schedule applies to at most one Monitor;
107
+ Monitor (as IntegratingMonitor) has IntegrationExclusion-Recurring Schedule; // Avoid ambiguity; this is a new fact type
108
+ Monitor (as IntegratingMonitor) has IntegrationExclusion-Recurring Schedule,
109
+ IntegrationExclusion-Recurring Schedule applies to at most one IntegratingMonitor;
118
110
  Recurring Schedule has one Duration;
111
+ Recurring Schedule has one Start-Time;
119
112
  Recurring Schedule friday;
120
113
  Recurring Schedule monday;
121
114
  Recurring Schedule saturday;
@@ -130,12 +123,12 @@ Satellite Message has at most one Message Data;
130
123
  Satellite Message has at most one Message Header;
131
124
  Satellite Message is of at most one Provider Type;
132
125
  Satellite Message has one Serial Number;
133
- Satellite Message has one insertion-Date Time YMDHMS;
126
+ Satellite Message has one insertion-Date Time;
134
127
 
135
128
  Subscription is identified by its Nr;
136
- Company has one Driver- Tech Subscription;
137
- Subscription has one Beginning-DateYYMMDD;
138
- Subscription has at most one Ending-DateYYMMDD;
129
+ Company has one DriverTech-Subscription;
130
+ Subscription has one Beginning-Date;
131
+ Subscription has at most one Ending-Date;
139
132
  Subscription is enabled;
140
133
 
141
134
  Switch is identified by its Id;
@@ -155,11 +148,6 @@ Switch is backup updates;
155
148
  Switch is send disabled;
156
149
  Switch is test vectors enabled;
157
150
 
158
- TimeHMS is identified by HHMMSS where
159
- TimeHMS has one HHMMSS,
160
- HHMMSS is of at most one TimeHMS;
161
- Recurring Schedule has one Start-TimeHMS;
162
-
163
151
  Transaction is identified by its Nr;
164
152
  Satellite Message has at most one Group-Transaction;
165
153
 
@@ -218,7 +206,7 @@ for each Credential exactly one of these holds:
218
206
  for each Network exactly one of these holds:
219
207
  Network is used by Host System,
220
208
  Company has Origin-Network,
221
- Tcp- Proxy Network is in Data Store;
209
+ TcpProxy-Network is in Data Store;
222
210
  for each Network exactly one of these holds:
223
211
  Network is ip_single,
224
212
  Network is ip_subnet,
@@ -241,7 +229,7 @@ Switch is on private Network
241
229
  Data Store has Legacy Switch;
242
230
  Client has default Data Store
243
231
  only if Client uses Data Store;
244
- Tcp Proxy Network is in Data Store
232
+ TcpProxy Network is in Data Store
245
233
  only if Network is ip_single;
246
234
  Network uses Domain Name
247
235
  only if Network is ip_single;
@@ -276,7 +264,7 @@ each Recurring Schedule occurs at least one time in
276
264
  each Service occurs one time in
277
265
  Vendor provides Service;
278
266
  each Subscription occurs at most one time in
279
- Company has Driver Tech Subscription;
267
+ Company has DriverTech Subscription;
280
268
  each Subscription occurs at most one time in
281
269
  Data Store Service has Subscription;
282
270
  each Switch occurs at most one time in
@@ -32,6 +32,3 @@ either Employee reports to Manager(1) or Employee is a Manager(2) that is a CEO
32
32
  Employee is a Manager that is a CEO that runs Company
33
33
  if and only if
34
34
  Employee works for Company;
35
- Employee(1) reports to Manager that is a kind of Employee(2) that works for Company
36
- if and only if
37
- Employee(1) works for Company;
@@ -3,7 +3,7 @@ vocabulary WindowInRoomInBldg;
3
3
  /*
4
4
  * Value Types
5
5
  */
6
- Building is written as Signed Integer(32);
6
+ Building Number is written as Signed Integer(32);
7
7
  Room Number is written as Signed Integer(32);
8
8
  Wall Number is written as Signed Integer(32);
9
9
  Window Number is written as Unsigned Integer(32);
@@ -11,12 +11,18 @@ Window Number is written as Unsigned Integer(32);
11
11
  /*
12
12
  * Entity Types
13
13
  */
14
+ Building is identified by its Number;
15
+
14
16
  Room is identified by Building and Room Number where
15
17
  Room is in one Building,
16
18
  Room has one Room Number;
17
19
 
18
- Window is identified by Room and Wall Number and Window Number where
19
- Window is in one Room,
20
- Window is located in one Wall Number,
20
+ Wall is identified by Room and Wall Number where
21
+ Wall is in one Room,
22
+ Room contains Wall,
23
+ Wall has one Wall Number;
24
+
25
+ Window is identified by Wall and Window Number where
26
+ Window is located in one Wall,
21
27
  Window has one Window Number;
22
28
 
@@ -80,7 +80,7 @@ vocabulary Units;
80
80
  1 pennyweight converts to pwt;
81
81
  100.0 kg converts to quintal;
82
82
  25.0 converts to quire;
83
- 0.5 pi converts to radian;
83
+ 0.5 pi^-1 converts to radian;
84
84
  500.0 converts to ream;
85
85
  1 converts to sec;
86
86
  1 sec converts to second;
@@ -9,3 +9,4 @@ require 'rubygems'
9
9
  require 'activefacts/version'
10
10
  require 'activefacts/support'
11
11
  require 'activefacts/api'
12
+ require 'activefacts/registry'
@@ -8,7 +8,6 @@ module ActiveFacts
8
8
  module CQL
9
9
  grammar CQL
10
10
  include LexicalRules
11
- include Language # One of the language modules provides this module
12
11
  include Expressions
13
12
  include Terms
14
13
  include ObjectTypes
@@ -110,6 +109,11 @@ module ActiveFacts
110
109
  }
111
110
  end
112
111
 
112
+ # An enforcement action, like SMS, email, log, alarm, etc.
113
+ rule action
114
+ id
115
+ end
116
+
113
117
  # presence constraint:
114
118
  rule presence_constraint
115
119
  (each_occurs_in_clauses / either_or)
@@ -9,8 +9,8 @@ module ActiveFacts
9
9
  grammar Context
10
10
  rule context_note
11
11
  '('
12
- w:who_says? s context_type discussion agreed:(',' a:as_agreed_by)? s
13
- ')'
12
+ s w:who_says? s context_type discussion agreed:(',' a:as_agreed_by)? s
13
+ ')' s
14
14
  {
15
15
  def value
16
16
  [ w.empty? ? nil : w.value, context_type.value, discussion.text_value, agreed.empty? ? [] : agreed.a.value]
@@ -35,11 +35,6 @@ module ActiveFacts
35
35
  to_avoid { def value; 'to_avoid'; end }
36
36
  end
37
37
 
38
- # An enforcement action, like SMS, email, log, alarm, etc.
39
- rule action
40
- id
41
- end
42
-
43
38
  rule discussion
44
39
  (
45
40
  '(' discussion ')' / (!( [()] / ',' as_agreed_by) .)*
@@ -53,11 +53,11 @@ module ActiveFacts
53
53
  end
54
54
 
55
55
  rule derived_variable
56
- variable:term s role_id:(role_name / subscript )?
56
+ derived:term s role_id:(role_name / subscript )?
57
57
  {
58
58
  def ast quantifier = nil, value_constraint = nil, literal = nil, nested_clauses = nil
59
59
  role_name = role_id.empty? ? nil : role_id.value
60
- variable.ast(quantifier, nil, role_name, value_constraint, literal, nested_clauses)
60
+ derived.ast(quantifier, nil, role_name, value_constraint, literal, nested_clauses)
61
61
  end
62
62
  }
63
63
  end
@@ -8,15 +8,16 @@ module ActiveFacts
8
8
  module CQL
9
9
  grammar FactTypes
10
10
  rule query
11
- s joined_clauses r:returning_clause? '?'
11
+ s query_clauses r:returning_clause? '?'
12
12
  {
13
13
  def ast
14
- Compiler::FactType.new nil, [], joined_clauses.ast, (r.empty? ? nil : r)
14
+ Compiler::FactType.new nil, [], query_clauses.ast, (r.empty? ? nil : r)
15
15
  end
16
16
  }
17
17
  end
18
18
 
19
19
  rule named_fact_type
20
+ s each?
20
21
  s term_definition_name
21
22
  mapping_pragmas is_where
22
23
  anonymous_fact_type
@@ -33,13 +34,13 @@ module ActiveFacts
33
34
  end
34
35
 
35
36
  rule anonymous_fact_type
36
- joined_clauses
37
- ctail:( (':' / where) s a:joined_clauses s)?
37
+ query_clauses
38
+ ctail:( (':' / where) s a:query_clauses s)?
38
39
  returning_clause?
39
40
  s ';'
40
41
  {
41
42
  def ast
42
- clauses_ast = joined_clauses.ast
43
+ clauses_ast = query_clauses.ast
43
44
  conditions = !ctail.empty? ? ctail.a.ast : []
44
45
  returning = respond_to?(:returning_clause) ? returning_clause.ast : nil
45
46
  value_derivation = clauses_ast.detect{|r| r.is_equality_comparison}
@@ -51,7 +52,7 @@ module ActiveFacts
51
52
  elsif (clauses_ast.size == 1 &&
52
53
  clauses_ast[0].phrases.size == 1 &&
53
54
  (popname = clauses_ast[0].phrases[0]) &&
54
- !popname.is_a?(Compiler::VarRef) &&
55
+ !popname.is_a?(Compiler::Reference) &&
55
56
  conditions.detect{|r| r.includes_literals}
56
57
  )
57
58
  Compiler::Fact.new conditions, popname
@@ -62,7 +63,7 @@ module ActiveFacts
62
63
  }
63
64
  end
64
65
 
65
- rule joined_clauses
66
+ rule query_clauses
66
67
  qualified_clauses
67
68
  # REVISIT: This creates no precedence between and/or, which could cause confusion.
68
69
  # Should disallow mixed conjuntions - using a sempred?
@@ -89,14 +90,14 @@ module ActiveFacts
89
90
  end
90
91
 
91
92
  rule qualified_clauses
92
- s q:qualifier? s contracted_clauses s p:post_qualifiers? s c:context_note?
93
+ s certainty s contracted_clauses s p:post_qualifiers? s c:context_note?
93
94
  {
94
95
  def ast(conjunction = nil)
95
96
  r = contracted_clauses.ast # An array of clause asts
96
97
  r[0].conjunction = conjunction
97
98
  # pre-qualifiers apply to the first clause, post_qualifiers and context_note to the last
98
99
  # REVISIT: This may be incorrect where the last is a nested clause
99
- r[0].qualifiers << q.text_value unless q.empty?
100
+ r[0].certainty = certainty.value
100
101
  r[-1].qualifiers += p.list unless p.empty?
101
102
  r[-1].context_note = c.ast unless c.empty?
102
103
  r
@@ -104,8 +105,14 @@ module ActiveFacts
104
105
  }
105
106
  end
106
107
 
107
- rule qualifier
108
- maybe / definitely
108
+ rule certainty
109
+ negative_prefix { def value; false; end }
110
+ /
111
+ maybe { def value; nil; end }
112
+ /
113
+ definitely { def value; true; end }
114
+ /
115
+ '' { def value; true; end }
109
116
  end
110
117
 
111
118
  rule post_qualifiers
@@ -119,7 +126,7 @@ module ActiveFacts
119
126
 
120
127
  rule post_qualifier
121
128
  static / transient /
122
- intransitive / transitive / acyclic / symmetric / asymmetric / antisymmetric / reflexive / irreflexive
129
+ intransitive / stronglyintransitive / transitive / acyclic / symmetric / asymmetric / antisymmetric / reflexive / irreflexive
123
130
  end
124
131
 
125
132
  rule clauses_list
@@ -173,7 +180,7 @@ module ActiveFacts
173
180
  end
174
181
 
175
182
  rule reading_contraction
176
- role p:post_qualifiers? conjunction:(that/who) s q:qualifier? s contracted_clauses s
183
+ role p:post_qualifiers? conjunction:(that/who) s certainty s contracted_clauses s
177
184
  {
178
185
  def ast
179
186
  # contracted_clauses.ast will return an array of Clauses, but the first clause is special. We must:
@@ -182,7 +189,7 @@ module ActiveFacts
182
189
  clauses_ast = contracted_clauses.ast
183
190
  clauses_ast[0].conjunction = conjunction.text_value
184
191
  clauses_ast[0].phrases.unshift(role.ast)
185
- clauses_ast[0].qualifiers << q.text_value unless q.empty? # Add maybe/definitely
192
+ clauses_ast[0].certainty = certainty.value
186
193
 
187
194
  # A contraction returns an array containing:
188
195
  # * a role AST
@@ -194,11 +201,11 @@ module ActiveFacts
194
201
  end
195
202
 
196
203
  rule condition_contraction
197
- role pq:post_qualifiers? q:qualifier? s comparator s e2:expression
204
+ role pq:post_qualifiers? certainty s comparator s e2:expression
198
205
  !phrase # The contracted_clauses must not continue here!
199
206
  {
200
207
  def ast
201
- c = Compiler::Comparison.new(comparator.text_value, role.ast, e2.ast, q.empty? ? [] : [q.text_value])
208
+ c = Compiler::Comparison.new(comparator.text_value, role.ast, e2.ast, certainty.value)
202
209
  c.conjunction = comparator.text_value
203
210
  [ role.ast, pq.empty? ? [] : pq.list, c ]
204
211
  end
@@ -206,22 +213,22 @@ module ActiveFacts
206
213
  end
207
214
 
208
215
  rule comparison
209
- e1:expression s q:qualifier? s comparator s contraction p:post_qualifiers?
216
+ e1:expression s certainty s comparator s contraction p:post_qualifiers?
210
217
  {
211
218
  def ast
212
219
  role, qualifiers, *clauses_ast = *contraction.ast
213
220
  clauses_ast[0].qualifiers += p.list unless p.empty? # apply post_qualifiers to the contracted clause
214
221
  # clauses_ast[0].conjunction = 'and' # AND is implicit for a contraction
215
- c = Compiler::Comparison.new(comparator.text_value, e1.ast, role)
216
- c.qualifiers << q.text_value unless q.empty?
222
+ c = Compiler::Comparison.new(comparator.text_value, e1.ast, role, certainty.value)
217
223
  [c] + clauses_ast
218
224
  end
219
225
  }
220
226
  /
221
- q:qualifier? e1:expression s comparator s e2:expression # comparisons have no post-qualifiers: p:post_qualifiers?
227
+ certainty e1:expression s comparator s e2:expression # comparisons have no post-qualifiers: p:post_qualifiers?
222
228
  {
223
229
  def ast
224
- [Compiler::Comparison.new(comparator.text_value, e1.ast, e2.ast, q.empty? ? [] : [q.text_value])]
230
+ c = Compiler::Comparison.new(comparator.text_value, e1.ast, e2.ast, certainty.value)
231
+ [c]
225
232
  end
226
233
  }
227
234
  end
@@ -257,13 +264,12 @@ module ActiveFacts
257
264
  end
258
265
 
259
266
  rule aggregate
260
- aggregate:id s of s term s # REVISIT: this term may need to pre-scanned in the qualified_clauses
261
- in s '('
262
- qualified_clauses # REVISIT: Need to test to verify this is the right level (not joined_clauses, etc)
263
- s ')'
267
+ aggregate:id s
268
+ agg_of s term_or_unary s agg_in s # REVISIT: this term may need to pre-scanned in the qualified_clauses
269
+ '(' qualified_clauses s ')' # REVISIT: Need to test to verify this is the right level (not query_clauses, etc)
264
270
  {
265
271
  def ast
266
- raise "Not implemented: AST for '#{aggregate.text_value} of #{term.text_value}'"
272
+ raise "Not implemented: AST for '#{aggregate.text_value} of #{term_or_unary.text_value}'"
267
273
  # This returns just the role with the nested clauses, which doesn't even work:
268
274
  term.ast(
269
275
  nil, # No quantifier
@@ -279,14 +285,14 @@ module ActiveFacts
279
285
 
280
286
  # This is the rule that causes most back-tracking. I think you can see why.
281
287
  rule simple_role
282
- q:(quantifier enforcement cn:context_note?)?
288
+ q:( quantifier enforcement cn:context_note? )?
283
289
  player:derived_variable
284
290
  lr:(
285
291
  literal u:unit?
286
292
  /
287
293
  value_constraint enforcement
288
294
  )?
289
- oj:objectification_join?
295
+ oj:objectification_step?
290
296
  {
291
297
  def ast
292
298
  if !q.empty? && q.quantifier.value
@@ -301,7 +307,7 @@ module ActiveFacts
301
307
  if lr.respond_to?(:literal)
302
308
  literal = Compiler::Literal.new(lr.literal.value, lr.u.empty? ? nil : lr.u.text_value)
303
309
  end
304
- value_constraint = Compiler::ValueConstraint.new(lr.value_constraint.ranges, lr.value_constraint.units, lr.enforcement.ast) if lr.respond_to?(:value_constraint)
310
+ value_constraint = Compiler::ValueConstraint.new(lr.value_constraint.ast, lr.enforcement.ast) if lr.respond_to?(:value_constraint)
305
311
  raise "It is not permitted to provide both a literal value and a value constraint" if value_constraint and literal
306
312
  end
307
313
 
@@ -318,8 +324,8 @@ module ActiveFacts
318
324
  }
319
325
  end
320
326
 
321
- rule objectification_join
322
- '(' s in_which s facts:joined_clauses s ')' s
327
+ rule objectification_step
328
+ '(' s in_which s facts:query_clauses s ')' s
323
329
  {
324
330
  def ast
325
331
  facts.ast