activefacts 0.8.6 → 0.8.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/Manifest.txt +33 -2
  2. data/README.rdoc +30 -36
  3. data/Rakefile +16 -20
  4. data/bin/afgen +17 -11
  5. data/bin/cql +313 -36
  6. data/download.html +43 -19
  7. data/examples/CQL/Address.cql +15 -15
  8. data/examples/CQL/Blog.cql +8 -8
  9. data/examples/CQL/CompanyDirectorEmployee.cql +6 -5
  10. data/examples/CQL/Death.cql +3 -3
  11. data/examples/CQL/Diplomacy.cql +48 -0
  12. data/examples/CQL/Genealogy.cql +41 -41
  13. data/examples/CQL/Insurance.cql +311 -0
  14. data/examples/CQL/JoinEquality.cql +35 -0
  15. data/examples/CQL/Marriage.cql +1 -1
  16. data/examples/CQL/Metamodel.cql +290 -185
  17. data/examples/CQL/MetamodelNext.cql +420 -0
  18. data/examples/CQL/Monogamy.cql +24 -0
  19. data/examples/CQL/MonthInSeason.cql +27 -0
  20. data/examples/CQL/Moon.cql +23 -0
  21. data/examples/CQL/MultiInheritance.cql +4 -4
  22. data/examples/CQL/NonRoleId.cql +14 -0
  23. data/examples/CQL/OddIdentifier.cql +18 -0
  24. data/examples/CQL/OilSupply.cql +24 -24
  25. data/examples/CQL/OneToOnes.cql +17 -0
  26. data/examples/CQL/Orienteering.cql +55 -55
  27. data/examples/CQL/OrienteeringER.cql +58 -0
  28. data/examples/CQL/PersonPlaysGame.cql +2 -2
  29. data/examples/CQL/RedundantDependency.cql +34 -0
  30. data/examples/CQL/SchoolActivities.cql +5 -5
  31. data/examples/CQL/SeparateSubtype.cql +28 -0
  32. data/examples/CQL/ServiceDirector.cql +283 -0
  33. data/examples/CQL/SimplestUnary.cql +2 -2
  34. data/examples/CQL/SubtypePI.cql +11 -11
  35. data/examples/CQL/Supervision.cql +38 -0
  36. data/examples/CQL/Tests.Test5.Load.cql +38 -0
  37. data/examples/CQL/WaiterTips.cql +33 -0
  38. data/examples/CQL/Warehousing.cql +55 -53
  39. data/examples/CQL/WindowInRoomInBldg.cql +9 -9
  40. data/examples/CQL/unit.cql +433 -544
  41. data/examples/index.html +314 -170
  42. data/examples/intro.html +6 -176
  43. data/examples/local.css +8 -4
  44. data/index.html +40 -25
  45. data/lib/activefacts/api/concept.rb +2 -2
  46. data/lib/activefacts/api/constellation.rb +4 -4
  47. data/lib/activefacts/api/instance.rb +2 -2
  48. data/lib/activefacts/api/instance_index.rb +4 -0
  49. data/lib/activefacts/api/numeric.rb +3 -1
  50. data/lib/activefacts/api/role.rb +1 -1
  51. data/lib/activefacts/api/standard_types.rb +23 -16
  52. data/lib/activefacts/api/support.rb +3 -1
  53. data/lib/activefacts/api/vocabulary.rb +4 -0
  54. data/lib/activefacts/cql/CQLParser.treetop +87 -39
  55. data/lib/activefacts/cql/Concepts.treetop +95 -69
  56. data/lib/activefacts/cql/Context.treetop +11 -2
  57. data/lib/activefacts/cql/Expressions.treetop +23 -59
  58. data/lib/activefacts/cql/FactTypes.treetop +141 -95
  59. data/lib/activefacts/cql/Language/English.treetop +33 -21
  60. data/lib/activefacts/cql/LexicalRules.treetop +6 -1
  61. data/lib/activefacts/cql/Terms.treetop +75 -26
  62. data/lib/activefacts/cql/ValueTypes.treetop +52 -54
  63. data/lib/activefacts/cql/compiler.rb +46 -1691
  64. data/lib/activefacts/cql/compiler/constraint.rb +602 -0
  65. data/lib/activefacts/cql/compiler/entity_type.rb +425 -0
  66. data/lib/activefacts/cql/compiler/fact.rb +300 -0
  67. data/lib/activefacts/cql/compiler/fact_type.rb +230 -0
  68. data/lib/activefacts/cql/compiler/reading.rb +832 -0
  69. data/lib/activefacts/cql/compiler/shared.rb +109 -0
  70. data/lib/activefacts/cql/compiler/value_type.rb +104 -0
  71. data/lib/activefacts/cql/parser.rb +132 -81
  72. data/lib/activefacts/generate/cql.rb +397 -274
  73. data/lib/activefacts/generate/oo.rb +13 -12
  74. data/lib/activefacts/generate/ordered.rb +107 -117
  75. data/lib/activefacts/generate/ruby.rb +34 -38
  76. data/lib/activefacts/generate/sql/mysql.rb +62 -45
  77. data/lib/activefacts/generate/sql/server.rb +59 -42
  78. data/lib/activefacts/input/cql.rb +6 -3
  79. data/lib/activefacts/input/orm.rb +991 -557
  80. data/lib/activefacts/persistence/columns.rb +16 -12
  81. data/lib/activefacts/persistence/foreignkey.rb +7 -4
  82. data/lib/activefacts/persistence/index.rb +3 -4
  83. data/lib/activefacts/persistence/reference.rb +5 -2
  84. data/lib/activefacts/support.rb +20 -14
  85. data/lib/activefacts/version.rb +1 -1
  86. data/lib/activefacts/vocabulary.rb +1 -0
  87. data/lib/activefacts/vocabulary/extensions.rb +328 -44
  88. data/lib/activefacts/vocabulary/metamodel.rb +145 -20
  89. data/lib/activefacts/vocabulary/verbaliser.rb +621 -0
  90. data/spec/absorption_spec.rb +4 -4
  91. data/spec/api/value_type.rb +1 -1
  92. data/spec/cql/context_spec.rb +45 -22
  93. data/spec/cql/deontic_spec.rb +88 -0
  94. data/spec/cql/matching_spec.rb +517 -0
  95. data/spec/cql/samples_spec.rb +88 -31
  96. data/spec/cql/unit_spec.rb +58 -37
  97. data/spec/cql_cql_spec.rb +12 -7
  98. data/spec/cql_mysql_spec.rb +3 -7
  99. data/spec/cql_parse_spec.rb +0 -4
  100. data/spec/cql_ruby_spec.rb +1 -4
  101. data/spec/cql_sql_spec.rb +5 -18
  102. data/spec/cql_symbol_tables_spec.rb +3 -0
  103. data/spec/cqldump_spec.rb +0 -2
  104. data/spec/helpers/array_matcher.rb +35 -0
  105. data/spec/helpers/ctrl_c_support.rb +52 -0
  106. data/spec/helpers/diff_matcher.rb +38 -0
  107. data/spec/helpers/file_matcher.rb +5 -3
  108. data/spec/helpers/string_matcher.rb +39 -0
  109. data/spec/helpers/test_parser.rb +13 -0
  110. data/spec/norma_cql_spec.rb +13 -5
  111. data/spec/norma_ruby_spec.rb +11 -3
  112. data/spec/{absorption_ruby_spec.rb → norma_ruby_sql_spec.rb} +37 -32
  113. data/spec/norma_sql_spec.rb +11 -5
  114. data/spec/norma_tables_spec.rb +33 -29
  115. data/spec/spec_helper.rb +4 -1
  116. data/status.html +92 -23
  117. metadata +102 -36
  118. data/lib/activefacts/generate/cql/html.rb +0 -403
@@ -0,0 +1,23 @@
1
+ vocabulary Moon;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ Moon Name is written as String;
7
+ Nr Days Nr is written as Signed Integer(32);
8
+ Planet Name is written as String;
9
+
10
+ /*
11
+ * Entity Types
12
+ */
13
+ Moon is identified by its Name;
14
+
15
+ Nr Days is identified by its Nr;
16
+
17
+ Orbit is where
18
+ Moon is in orbit;
19
+ Orbit has a synodic period of at most one Nr Days;
20
+
21
+ Planet is identified by its Name;
22
+ Orbit is around one Planet;
23
+
@@ -3,9 +3,9 @@ vocabulary MultiInheritance;
3
3
  /*
4
4
  * Value Types
5
5
  */
6
- EmployeeID is written as AutoCounter;
7
- PersonName is written as VariableLengthText;
8
- TFN is written as FixedLengthText(9);
6
+ Employee ID is written as Auto Counter;
7
+ Person Name is written as String;
8
+ TFN is written as Char(9);
9
9
 
10
10
  /*
11
11
  * Entity Types
@@ -18,5 +18,5 @@ Australian has at most one TFN,
18
18
 
19
19
  Employee is a kind of Person identified by its ID;
20
20
 
21
- AustralianEmployee is a kind of Employee, Australian;
21
+ Australian Employee is a kind of Employee, Australian;
22
22
 
@@ -0,0 +1,14 @@
1
+ vocabulary NonRoleId;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ Comparison Id is written as Auto Counter;
7
+ Ordinal is written as Auto Counter;
8
+
9
+ /*
10
+ * Entity Types
11
+ */
12
+ Comparison is identified by its Id where
13
+ Ordinal comes before larger-Ordinal;
14
+
@@ -0,0 +1,18 @@
1
+ vocabulary OddIdentifier;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ Ordinal is written as Signed Integer(32);
7
+ Text is written as String;
8
+ Thing ID is written as Auto Counter;
9
+
10
+ /*
11
+ * Entity Types
12
+ */
13
+ Thing is identified by its ID;
14
+
15
+ Thing Sequence is identified by Thing and Text where
16
+ Thing has Ordinal occurrence,
17
+ Thing Sequence has one Text;
18
+
@@ -4,19 +4,19 @@ vocabulary OilSupply;
4
4
  * Value Types
5
5
  */
6
6
  Cost is written as Money;
7
- MonthCode is written as FixedLengthText;
8
- ProductName is written as VariableLengthText;
9
- Quantity is written as UnsignedInteger(32);
10
- RefineryName is written as VariableLengthText(80);
11
- RegionName is written as VariableLengthText;
12
- Season is written as VariableLengthText(6) restricted to {'Autumn', 'Spring', 'Summer', 'Winter'};
13
- TransportMethod is written as VariableLengthText restricted to {'Rail', 'Road', 'Sea'};
14
- YearNr is written as SignedInteger(32);
7
+ Month Nr is written as Signed Integer(32);
8
+ Product Name is written as String;
9
+ Quantity is written as Unsigned Integer(32);
10
+ Refinery Name is written as String(80);
11
+ Region Name is written as String;
12
+ Season is written as String(6) restricted to {'Autumn', 'Spring', 'Summer', 'Winter'};
13
+ Transport Method is written as String restricted to {'Rail', 'Road', 'Sea'};
14
+ Year Nr is written as Signed Integer(32);
15
15
 
16
16
  /*
17
17
  * Entity Types
18
18
  */
19
- Month is identified by its Code;
19
+ Month is identified by its Nr restricted to {1..12};
20
20
  Month is in one Season;
21
21
 
22
22
  Product is identified by its Name;
@@ -25,27 +25,27 @@ Refinery is identified by its Name;
25
25
 
26
26
  Region is identified by its Name;
27
27
 
28
- TransportRoute is where
29
- TransportMethod transportation is available from Refinery to Region,
30
- TransportMethod transportation is available to Region from Refinery;
31
- TransportRoute incurs at most one Cost per kl;
28
+ Transport Route is where
29
+ Transport Method transportation is available from Refinery to Region,
30
+ Transport Method transportation is available to Region from Refinery;
31
+ Transport Route incurs at most one Cost per kl;
32
32
 
33
33
  Year is identified by its Nr;
34
34
 
35
- AcceptableSubstitutes is where
35
+ Acceptable Substitutes is where
36
36
  Product may be substituted by alternate-Product in Season [acyclic, intransitive],
37
37
  alternate-Product is an acceptable substitute for Product in Season;
38
38
 
39
- SupplyPeriod is identified by Year and Month where
40
- SupplyPeriod is in one Year,
41
- SupplyPeriod is in one Month;
39
+ Supply Period is identified by Year and Month where
40
+ Supply Period is in one Year,
41
+ Supply Period is in one Month;
42
42
 
43
- ProductionForecast is where
44
- Refinery forecasts production of Product in SupplyPeriod;
45
- ProductionForecast predicts at most one Cost;
46
- ProductionForecast is for one Quantity;
43
+ Production Forecast is where
44
+ Refinery forecasts production of Product in Supply Period;
45
+ Production Forecast predicts at most one Cost;
46
+ Production Forecast is for one Quantity;
47
47
 
48
- RegionalDemand is where
49
- Region will need Product in SupplyPeriod;
50
- RegionalDemand is for at most one Quantity;
48
+ Regional Demand is where
49
+ Region will need Product in Supply Period;
50
+ Regional Demand is for at most one Quantity;
51
51
 
@@ -0,0 +1,17 @@
1
+ vocabulary OneToOnes;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ Boy ID is written as Auto Counter;
7
+ Girl ID is written as Auto Counter;
8
+
9
+ /*
10
+ * Entity Types
11
+ */
12
+ Boy is identified by its ID [independent];
13
+
14
+ Girl is identified by its ID [independent];
15
+ Girl is going out with at most one Boy,
16
+ Boy is going out with at most one Girl;
17
+
@@ -3,58 +3,58 @@ vocabulary Orienteering;
3
3
  /*
4
4
  * Value Types
5
5
  */
6
- Accessibility is written as FixedLengthText(1) restricted to {'A'..'D'};
7
- ClubCode is written as VariableLengthText(6);
8
- ClubName is written as VariableLengthText(32);
9
- ControlNumber is written as UnsignedInteger(32) restricted to {1..1000};
10
- Course is written as VariableLengthText(16) restricted to {'A'..'E', 'PW'};
11
- EntryID is written as AutoCounter;
12
- EventID is written as AutoCounter;
13
- EventName is written as VariableLengthText(50);
14
- FamilyName is written as VariableLengthText(48);
15
- Gender is written as FixedLengthText(1) restricted to {'F', 'M'};
16
- GivenName is written as VariableLengthText(48);
17
- Location is written as VariableLengthText(200);
18
- MapID is written as AutoCounter;
19
- MapName is written as VariableLengthText(80);
20
- Number is written as UnsignedInteger(32) restricted to {1..100};
21
- PersonID is written as AutoCounter;
22
- Placing is written as UnsignedInteger(32);
23
- PointValue is written as UnsignedInteger(32);
24
- PostCode is written as UnsignedInteger(32);
25
- PunchID is written as AutoCounter;
26
- Score is written as SignedInteger(32);
27
- ScoringMethod is written as VariableLengthText(32) restricted to {'Scatter', 'Score', 'Special'};
28
- SeriesID is written as AutoCounter;
29
- SeriesName is written as VariableLengthText(40);
30
- StartTime is written as DateAndTime;
31
- Time is written as DateAndTime;
32
- Year is written as UnsignedInteger(32) restricted to {1900..3000};
6
+ Accessibility is written as Char(1) restricted to {'A'..'D'};
7
+ Club Code is written as String(6);
8
+ Club Name is written as String(32);
9
+ Control Number is written as Unsigned Integer(32) restricted to {1..1000};
10
+ Course is written as String(16) restricted to {'A'..'E', 'PW'};
11
+ Entry ID is written as Auto Counter;
12
+ Event ID is written as Auto Counter;
13
+ Event Name is written as String(50);
14
+ Family Name is written as String(48);
15
+ Gender is written as Char(1) restricted to {'F', 'M'};
16
+ Given Name is written as String(48);
17
+ Location is written as String(200);
18
+ Map ID is written as Auto Counter;
19
+ Map Name is written as String(80);
20
+ Number is written as Unsigned Integer(32) restricted to {1..100};
21
+ Person ID is written as Auto Counter;
22
+ Placing is written as Unsigned Integer(32);
23
+ Point Value is written as Unsigned Integer(32);
24
+ Post Code is written as Unsigned Integer(32);
25
+ Punch ID is written as Auto Counter;
26
+ Score is written as Signed Integer(32);
27
+ Scoring Method is written as String(32) restricted to {'Scatter', 'Score', 'Special'};
28
+ Series ID is written as Auto Counter;
29
+ Series Name is written as String(40);
30
+ Start Time is written as Date Time;
31
+ Time is written as Date Time;
32
+ Year is written as Unsigned Integer(32) restricted to {1900..3000};
33
33
 
34
34
  /*
35
35
  * Entity Types
36
36
  */
37
37
  Club is identified by its Code;
38
- ClubName is name of at most one Club,
39
- Club is called one ClubName;
38
+ Club Name is name of at most one Club,
39
+ Club is called one Club Name;
40
40
 
41
41
  Event is identified by its ID;
42
42
  Club runs Event,
43
43
  Event is run by one Club;
44
- Event is called at most one EventName,
45
- EventName is name of at most one Event;
44
+ Event is called at most one Event Name,
45
+ Event Name is name of at most one Event;
46
46
  Event has at most one Number;
47
- Event is held on one StartTime;
47
+ Event is held on one Start Time;
48
48
  Event starts at one start-Location,
49
- Location is where Event starts;
49
+ Location is place Event starts;
50
50
 
51
- EventControl is where
52
- Event includes at least one ControlNumber;
53
- EventControl has at most one PointValue;
51
+ Event Control is where
52
+ Event includes at least one Control Number;
53
+ Event Control has at most one Point Value;
54
54
 
55
- EventScoringMethod is where
56
- ScoringMethod is used for Course of Event,
57
- Course of Event uses at most one ScoringMethod;
55
+ Event Scoring Method is where
56
+ Scoring Method is used for Course of Event,
57
+ Course of Event uses at most one Scoring Method;
58
58
 
59
59
  Map is identified by its ID;
60
60
  Club (as Owner) owns Map,
@@ -62,27 +62,27 @@ Club (as Owner) owns Map,
62
62
  Map has at most one Accessibility;
63
63
  Map is map for Event,
64
64
  Event uses one Map;
65
- Map has one MapName,
66
- MapName is of at most one Map;
65
+ Map has one Map Name,
66
+ Map Name is of at most one Map;
67
67
 
68
68
  Person is identified by its ID;
69
69
  Person is member of at most one Club;
70
- Person has one FamilyName,
71
- FamilyName is of Person;
70
+ Person has one Family Name,
71
+ Family Name is of Person;
72
72
  Person is of at most one Gender;
73
- Person has one GivenName,
74
- GivenName is name of Person;
75
- Person has at most one PostCode;
73
+ Person has one Given Name,
74
+ Given Name is name of Person;
75
+ Person has at most one Post Code;
76
76
  Person was born in at most one birth-Year;
77
77
 
78
78
  Punch is identified by its ID;
79
79
 
80
- PunchPlacement is where
81
- Punch is placed at EventControl;
80
+ Punch Placement is where
81
+ Punch is placed at Event Control;
82
82
 
83
83
  Series is identified by its ID;
84
84
  Event is in at most one Series;
85
- Series has one SeriesName (as Name),
85
+ Series has one Series Name (as Name),
86
86
  Name is of at most one Series;
87
87
 
88
88
  Entry is identified by its ID where
@@ -100,12 +100,12 @@ Visit is where
100
100
  Event is in Series
101
101
  if and only if
102
102
  Event has Number;
103
- either Event is called EventName or Event is in Series;
104
- each EventControl occurs at least one time in
105
- Punch is placed at EventControl;
106
- each combination GivenName, FamilyName occurs at most one time in
107
- Person has GivenName,
108
- Person has FamilyName;
103
+ each Event Control occurs at least one time in
104
+ Punch is placed at Event Control;
105
+ either Event is called Event Name or Event is in Series;
106
+ each combination Given Name, Family Name occurs at most one time in
107
+ Person has Given Name,
108
+ Person has Family Name;
109
109
  each combination Series, Number occurs at most one time in
110
110
  Event is in Series,
111
111
  Event has Number;
@@ -0,0 +1,58 @@
1
+ vocabulary OrienteeringER;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ Accessibility is written as Char;
7
+ Club Name is written as String;
8
+ Code is written as Char;
9
+ Control is written as Unsigned Integer(32);
10
+ Course is written as Char;
11
+ Date is written as Date Time;
12
+ Event Name is written as String;
13
+ ID is written as Auto Counter;
14
+ Location is written as String;
15
+ Name is written as String;
16
+ Number is written as Signed Integer(32);
17
+ Point Value is written as Unsigned Integer(32);
18
+ Series Name is written as String;
19
+
20
+ /*
21
+ * Entity Types
22
+ */
23
+ Club is where
24
+ Code is of the club called at most one Club Name,
25
+ the club called Club Name has at most one Code;
26
+
27
+ Map is where
28
+ map-Name having Accessibility belongs to Club;
29
+
30
+ Series Event is where
31
+ Series Name includes event-Number,
32
+ event-Number is in Series Name;
33
+
34
+ Event is where
35
+ event-ID is Series Event called Event Name run by Club using Map on Date at Location;
36
+
37
+ Event Control is where
38
+ Event includes Control which is worth at most one Point Value;
39
+
40
+ Event Course is where
41
+ Course is available at Event,
42
+ Event offers Course;
43
+
44
+ /*
45
+ * Constraints:
46
+ */
47
+ each Club occurs at least one time in
48
+ event ID is Series Event called Event Name run by Club using Map on Date at Location;
49
+ each Event Name occurs at most one time in
50
+ event ID is Series Event called Event Name run by Club using Map on Date at Location;
51
+ each Event occurs at least one time in
52
+ Event includes Control which is worth Point Value;
53
+ each ID occurs one time in
54
+ event ID is Series Event called Event Name run by Club using Map on Date at Location;
55
+ each Name occurs at most one time in
56
+ map Name having Accessibility belongs to Club;
57
+ each Series Event occurs at most one time in
58
+ event ID is Series Event called Event Name run by Club using Map on Date at Location;
@@ -3,8 +3,8 @@ vocabulary PersonPlaysGame;
3
3
  /*
4
4
  * Value Types
5
5
  */
6
- GameCode is written as FixedLengthText;
7
- PersonName is written as VariableLengthText;
6
+ Game Code is written as Char;
7
+ Person Name is written as String;
8
8
 
9
9
  /*
10
10
  * Entity Types
@@ -0,0 +1,34 @@
1
+ vocabulary RedundantDependency;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ Address Id is written as Auto Counter;
7
+ District Number is written as Signed Integer(32);
8
+ Politician Id is written as Auto Counter;
9
+ Postal Code is written as Signed Integer(32);
10
+ State Or Province Id is written as Auto Counter;
11
+
12
+ /*
13
+ * Entity Types
14
+ */
15
+ Address is identified by its Id;
16
+ Address is assigned at most one Postal Code;
17
+
18
+ Politician is identified by its Id;
19
+
20
+ State Or Province is identified by its Id;
21
+ Address is in at most one State Or Province;
22
+
23
+ Legislative District is identified by District Number and State Or Province where
24
+ Legislative District has one District Number,
25
+ Legislative District is for one State Or Province;
26
+ Address is in at most one Legislative District;
27
+ Politician represents at most one Legislative District,
28
+ Legislative District is represented by one Politician;
29
+
30
+ /*
31
+ * Constraints:
32
+ */
33
+ Address is in Legislative District
34
+ only if Address is in State Or Province and Legislative District is for State Or Province;
@@ -3,9 +3,9 @@ vocabulary SchoolActivities;
3
3
  /*
4
4
  * Value Types
5
5
  */
6
- ActivityName is written as VariableLengthText(32);
7
- SchoolName is written as VariableLengthText;
8
- StudentName is written as VariableLengthText;
6
+ Activity Name is written as String(32);
7
+ School Name is written as String;
8
+ Student Name is written as String;
9
9
 
10
10
  /*
11
11
  * Entity Types
@@ -14,13 +14,13 @@ Activity is identified by its Name;
14
14
 
15
15
  School is identified by its Name;
16
16
 
17
- SchoolActivity is where
17
+ School Activity is where
18
18
  School sanctions Activity;
19
19
 
20
20
  Student is identified by its Name;
21
21
  Student is enrolled in one School;
22
22
 
23
- StudentParticipation is where
23
+ Student Participation is where
24
24
  Student represents School in Activity,
25
25
  Student participates in Activity which is sanctioned by at most one School;
26
26