activefacts 0.6.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 (84) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +83 -0
  3. data/README.rdoc +81 -0
  4. data/Rakefile +41 -0
  5. data/bin/afgen +46 -0
  6. data/bin/cql +52 -0
  7. data/examples/CQL/Address.cql +46 -0
  8. data/examples/CQL/Blog.cql +54 -0
  9. data/examples/CQL/CompanyDirectorEmployee.cql +51 -0
  10. data/examples/CQL/Death.cql +16 -0
  11. data/examples/CQL/Genealogy.cql +95 -0
  12. data/examples/CQL/Marriage.cql +18 -0
  13. data/examples/CQL/Metamodel.cql +238 -0
  14. data/examples/CQL/MultiInheritance.cql +19 -0
  15. data/examples/CQL/OilSupply.cql +47 -0
  16. data/examples/CQL/Orienteering.cql +108 -0
  17. data/examples/CQL/PersonPlaysGame.cql +17 -0
  18. data/examples/CQL/SchoolActivities.cql +31 -0
  19. data/examples/CQL/SimplestUnary.cql +12 -0
  20. data/examples/CQL/SubtypePI.cql +32 -0
  21. data/examples/CQL/Warehousing.cql +99 -0
  22. data/examples/CQL/WindowInRoomInBldg.cql +22 -0
  23. data/lib/activefacts.rb +10 -0
  24. data/lib/activefacts/api.rb +25 -0
  25. data/lib/activefacts/api/concept.rb +384 -0
  26. data/lib/activefacts/api/constellation.rb +106 -0
  27. data/lib/activefacts/api/entity.rb +239 -0
  28. data/lib/activefacts/api/instance.rb +54 -0
  29. data/lib/activefacts/api/numeric.rb +158 -0
  30. data/lib/activefacts/api/role.rb +94 -0
  31. data/lib/activefacts/api/standard_types.rb +67 -0
  32. data/lib/activefacts/api/support.rb +59 -0
  33. data/lib/activefacts/api/value.rb +122 -0
  34. data/lib/activefacts/api/vocabulary.rb +120 -0
  35. data/lib/activefacts/cql.rb +31 -0
  36. data/lib/activefacts/cql/CQLParser.treetop +104 -0
  37. data/lib/activefacts/cql/Concepts.treetop +112 -0
  38. data/lib/activefacts/cql/DataTypes.treetop +66 -0
  39. data/lib/activefacts/cql/Expressions.treetop +113 -0
  40. data/lib/activefacts/cql/FactTypes.treetop +185 -0
  41. data/lib/activefacts/cql/Language/English.treetop +92 -0
  42. data/lib/activefacts/cql/LexicalRules.treetop +169 -0
  43. data/lib/activefacts/cql/Rakefile +6 -0
  44. data/lib/activefacts/cql/parser.rb +88 -0
  45. data/lib/activefacts/generate/absorption.rb +87 -0
  46. data/lib/activefacts/generate/cql.rb +441 -0
  47. data/lib/activefacts/generate/cql/html.rb +397 -0
  48. data/lib/activefacts/generate/null.rb +19 -0
  49. data/lib/activefacts/generate/ordered.rb +557 -0
  50. data/lib/activefacts/generate/ruby.rb +326 -0
  51. data/lib/activefacts/generate/sql/server.rb +164 -0
  52. data/lib/activefacts/generate/text.rb +21 -0
  53. data/lib/activefacts/input/cql.rb +1268 -0
  54. data/lib/activefacts/input/orm.rb +926 -0
  55. data/lib/activefacts/persistence.rb +1 -0
  56. data/lib/activefacts/persistence/composition.rb +653 -0
  57. data/lib/activefacts/support.rb +51 -0
  58. data/lib/activefacts/version.rb +3 -0
  59. data/lib/activefacts/vocabulary.rb +6 -0
  60. data/lib/activefacts/vocabulary/extensions.rb +343 -0
  61. data/lib/activefacts/vocabulary/metamodel.rb +303 -0
  62. data/script/txt2html +71 -0
  63. data/spec/absorption_spec.rb +95 -0
  64. data/spec/api/autocounter.rb +82 -0
  65. data/spec/api/constellation.rb +130 -0
  66. data/spec/api/entity_type.rb +101 -0
  67. data/spec/api/instance.rb +428 -0
  68. data/spec/api/roles.rb +122 -0
  69. data/spec/api/value_type.rb +112 -0
  70. data/spec/api_spec.rb +14 -0
  71. data/spec/cql_cql_spec.rb +58 -0
  72. data/spec/cql_parse_spec.rb +31 -0
  73. data/spec/cql_ruby_spec.rb +60 -0
  74. data/spec/cql_sql_spec.rb +54 -0
  75. data/spec/cql_symbol_tables_spec.rb +259 -0
  76. data/spec/cql_unit_spec.rb +336 -0
  77. data/spec/cqldump_spec.rb +169 -0
  78. data/spec/norma_cql_spec.rb +48 -0
  79. data/spec/norma_ruby_spec.rb +50 -0
  80. data/spec/norma_sql_spec.rb +45 -0
  81. data/spec/norma_tables_spec.rb +94 -0
  82. data/spec/spec.opts +1 -0
  83. data/spec/spec_helper.rb +10 -0
  84. metadata +173 -0
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.6.0 2008-11-27
2
+
3
+ * 1 major enhancement:
4
+ * Initial public release
data/Manifest.txt ADDED
@@ -0,0 +1,83 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ bin/afgen
6
+ bin/cql
7
+ examples/CQL/Address.cql
8
+ examples/CQL/Blog.cql
9
+ examples/CQL/CompanyDirectorEmployee.cql
10
+ examples/CQL/Death.cql
11
+ examples/CQL/Genealogy.cql
12
+ examples/CQL/Marriage.cql
13
+ examples/CQL/Metamodel.cql
14
+ examples/CQL/MultiInheritance.cql
15
+ examples/CQL/OilSupply.cql
16
+ examples/CQL/Orienteering.cql
17
+ examples/CQL/PersonPlaysGame.cql
18
+ examples/CQL/SchoolActivities.cql
19
+ examples/CQL/SimplestUnary.cql
20
+ examples/CQL/SubtypePI.cql
21
+ examples/CQL/Warehousing.cql
22
+ examples/CQL/WindowInRoomInBldg.cql
23
+ lib/activefacts.rb
24
+ lib/activefacts/api.rb
25
+ lib/activefacts/api/concept.rb
26
+ lib/activefacts/api/constellation.rb
27
+ lib/activefacts/api/entity.rb
28
+ lib/activefacts/api/instance.rb
29
+ lib/activefacts/api/numeric.rb
30
+ lib/activefacts/api/role.rb
31
+ lib/activefacts/api/standard_types.rb
32
+ lib/activefacts/api/support.rb
33
+ lib/activefacts/api/value.rb
34
+ lib/activefacts/api/vocabulary.rb
35
+ lib/activefacts/cql.rb
36
+ lib/activefacts/cql/Rakefile
37
+ lib/activefacts/cql/CQLParser.treetop
38
+ lib/activefacts/cql/Concepts.treetop
39
+ lib/activefacts/cql/DataTypes.treetop
40
+ lib/activefacts/cql/Expressions.treetop
41
+ lib/activefacts/cql/FactTypes.treetop
42
+ lib/activefacts/cql/Language/English.treetop
43
+ lib/activefacts/cql/LexicalRules.treetop
44
+ lib/activefacts/cql/parser.rb
45
+ lib/activefacts/generate/absorption.rb
46
+ lib/activefacts/generate/cql.rb
47
+ lib/activefacts/generate/cql/html.rb
48
+ lib/activefacts/generate/null.rb
49
+ lib/activefacts/generate/ordered.rb
50
+ lib/activefacts/generate/ruby.rb
51
+ lib/activefacts/generate/sql/server.rb
52
+ lib/activefacts/generate/text.rb
53
+ lib/activefacts/input/cql.rb
54
+ lib/activefacts/input/orm.rb
55
+ lib/activefacts/persistence.rb
56
+ lib/activefacts/persistence/composition.rb
57
+ lib/activefacts/support.rb
58
+ lib/activefacts/version.rb
59
+ lib/activefacts/vocabulary.rb
60
+ lib/activefacts/vocabulary/extensions.rb
61
+ lib/activefacts/vocabulary/metamodel.rb
62
+ script/txt2html
63
+ spec/absorption_spec.rb
64
+ spec/api/autocounter.rb
65
+ spec/api/constellation.rb
66
+ spec/api/entity_type.rb
67
+ spec/api/instance.rb
68
+ spec/api/roles.rb
69
+ spec/api/value_type.rb
70
+ spec/api_spec.rb
71
+ spec/cql_cql_spec.rb
72
+ spec/cql_parse_spec.rb
73
+ spec/cql_ruby_spec.rb
74
+ spec/cql_sql_spec.rb
75
+ spec/cql_symbol_tables_spec.rb
76
+ spec/cql_unit_spec.rb
77
+ spec/cqldump_spec.rb
78
+ spec/norma_cql_spec.rb
79
+ spec/norma_ruby_spec.rb
80
+ spec/norma_sql_spec.rb
81
+ spec/norma_tables_spec.rb
82
+ spec/spec.opts
83
+ spec/spec_helper.rb
data/README.rdoc ADDED
@@ -0,0 +1,81 @@
1
+ = activefacts
2
+
3
+ * http://dataconstellation.com/ActiveFacts/
4
+
5
+ == DESCRIPTION:
6
+
7
+ ActiveFacts is a semantic modeling toolkit, comprising an implementation
8
+ of the Constellation Query Language, the Constellation API, and code
9
+ generators that receive CQL or ORM (Object Role Modeling files, from
10
+ NORMA) to emit CQL, Ruby and SQL.
11
+
12
+ Semantic modeling is a refinement of fact-based modeling techniques
13
+ that draw on natural language verbalisation and formal logic. Fact
14
+ based modeling is essentially the same as relational modeling in the
15
+ sixth normal form. The tools provided here automatically condense
16
+ that to third normal form for efficient storage. They also generate
17
+ object models as a Ruby module which has an effective mapping to
18
+ both the original semantic model and to the generated SQL.
19
+
20
+ The result is a formal language that reads like plain English, and
21
+ allows creation of relational and object models that are guaranteed
22
+ equivalent, and much more stable in the face of schema evolution than
23
+ SQL is.
24
+
25
+ == FEATURES/PROBLEMS:
26
+
27
+ * Queries are parsed, but not yet generated to SQL. DDL is complete.
28
+
29
+ * SQL generation handles some one-to-one relationships wrongly,
30
+ including subtypes when independent of the supertype's table.
31
+
32
+ * The Constellation API lacks SQL persistence (but is already useful;
33
+ the CQL compiler uses the generated Ruby code extensively)
34
+
35
+ * Re-invoking a fact type to add new readings doesn't work
36
+
37
+ * Some types of external constraints (when adjectives mis-match)
38
+ don't yet pass the CQL parser's semantic analysis.
39
+
40
+ * Validation of semantic models (and many other areas) is incomplete
41
+
42
+ * There's no interactive CQL interpreter yet; the cql command merely
43
+ shows the parse tree.
44
+
45
+ == SYNOPSIS:
46
+
47
+ afgen --sql/server myfile.cql
48
+ afgen --ruby myfile.cql
49
+ afgen --cql myfile.orm
50
+
51
+ == REQUIREMENTS:
52
+
53
+ * Treetop parser generator
54
+ * Optional: NORMA, see <http://www.ormfoundation.org/files/>
55
+ (needs Visual Studio pro edition), if you want to use ORM
56
+
57
+ == INSTALL:
58
+
59
+ * sudo gem install activefacts
60
+
61
+ == LICENSE:
62
+
63
+ Copyright (c) 2008 Clifford Heath.
64
+
65
+ This software is provided 'as-is', without any express or implied warranty.
66
+ In no event will the authors be held liable for any damages arising from the
67
+ use of this software.
68
+
69
+ Permission is granted to anyone to use this software for any purpose,
70
+ including commercial applications, and to alter it and redistribute it
71
+ freely, subject to the following restrictions:
72
+
73
+ 1. The origin of this software must not be misrepresented; you must not
74
+ claim that you wrote the original software. If you use this software
75
+ in a product, an acknowledgment in the product documentation would be
76
+ appreciated but is not required.
77
+
78
+ 2. Altered source versions must be plainly marked as such, and must not be
79
+ misrepresented as being the original software.
80
+
81
+ 3. This notice may not be removed or altered from any source distribution.
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen spec spec/rake/spectask].each { |f| require f }
2
+
3
+ require File.dirname(__FILE__) + '/lib/activefacts'
4
+
5
+ # Generate all the Rake tasks
6
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
7
+ $hoe = Hoe.new('activefacts', ActiveFacts::VERSION) do |p|
8
+ p.developer('Clifford Heath', 'cjh@dataconstellation.org')
9
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
+ p.post_install_message = 'For more information on ActiveFacts, see http://dataconstellation.com/ActiveFacts'
11
+ p.rubyforge_name = "cjheath@rubyforge.org"
12
+ p.extra_deps = [
13
+ ['treetop','>= 1.2.4'],
14
+ ]
15
+ p.extra_dev_deps = [
16
+ ['newgem', ">= #{::Newgem::VERSION}"]
17
+ ]
18
+ p.spec_extras[:extensions] = 'lib/activefacts/cql/Rakefile'
19
+ p.spec_extras[:rdoc_options] = [
20
+ "-x", "lib/activefacts/cql/.*.rb",
21
+ "-x", "lib/activefacts/vocabulary/.*.rb",
22
+ "-x", "lib/activefacts/persistence/.*.rb",
23
+ ]
24
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
25
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
26
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
27
+ p.rsync_args = '-av --delete --ignore-errors'
28
+ end
29
+
30
+ require 'newgem/tasks' # load /tasks/*.rake
31
+ Dir['tasks/**/*.rake'].each { |t| load t }
32
+
33
+ # TODO - want other tests/tasks run by default? Add them to the list
34
+ # task :default => [:spec, :features]
35
+
36
+ Spec::Rake::SpecTask.new(:spec) do |t|
37
+ t.ruby_opts = ['-I', "lib"]
38
+ t.spec_files = FileList['spec/**/*_spec.rb']
39
+ # t.rcov = true
40
+ # t.rcov_opts = ['--exclude', 'spec,/usr/lib/ruby' ]
41
+ end
data/bin/afgen ADDED
@@ -0,0 +1,46 @@
1
+ #! env ruby
2
+ #
3
+ # Read an ORM2 Vocabulary from a NORMA, CQL or other file
4
+ #
5
+ # Copyright (c) 2007 Clifford Heath. Read the LICENSE file.
6
+ #
7
+ $:.unshift File.dirname(File.expand_path(__FILE__))+"/../lib"
8
+
9
+ require 'rubygems'
10
+ require 'ruby-debug'
11
+ require 'activefacts'
12
+ require 'activefacts/vocabulary'
13
+
14
+ arg = ARGV.shift
15
+
16
+ # Load the required generator, or the default "text" generator:
17
+ generator = "text"
18
+ if arg =~ /^--([^=]*)(?:=(.*))?/
19
+ generator = $1
20
+ generator_options = ($2||"").split(/,/)
21
+ arg = ARGV.shift
22
+ end
23
+ output_handler = "activefacts/generate/#{generator.downcase}"
24
+ require output_handler
25
+ output_class = generator.upcase.gsub(%r{[/\\]+},'::')
26
+ output_klass = eval("ActiveFacts::Generate::#{output_class}")
27
+ raise "Expected #{output_handler} to define #{output_class}" unless output_klass
28
+
29
+ # Load the file type input method
30
+ extension = arg.sub(/\A.*\./,'').downcase
31
+ input_handler = "activefacts/input/#{extension}"
32
+ require input_handler
33
+ input_class = extension.upcase
34
+ input_klass = ActiveFacts::Input.const_get(input_class.to_sym)
35
+ raise "Expected #{input_handler} to define #{input_class}" unless input_klass
36
+
37
+ # Read the input file:
38
+ begin
39
+ vocabulary = input_klass.readfile(arg)
40
+ rescue => e
41
+ puts "#{e.message}"
42
+ puts "#{e}:\n\t#{e.backtrace*"\n\t"}" if debug
43
+ end
44
+
45
+ # Generate the output:
46
+ output_klass.new(vocabulary, *generator_options).generate if vocabulary
data/bin/cql ADDED
@@ -0,0 +1,52 @@
1
+ #! env ruby
2
+ #
3
+ # Interactive CQL command-line.
4
+ # Copyright (c) 2007 Clifford Heath. Read the LICENSE file.
5
+ #
6
+
7
+ require 'activefacts'
8
+ require 'activefacts/cql/parser'
9
+ require 'readline'
10
+
11
+ puts "This is a stub for the CQL interactive commandline. At the moment it only parses CQL and shows the parse trees."
12
+
13
+ parser = ActiveFacts::CQLParser.new
14
+ parser.root = :definition
15
+ statement = nil
16
+ while line = Readline::readline(statement ? "CQL+ " : "CQL? ", [])
17
+ statement = statement ? statement + "\n"+line : line
18
+ if line =~ %r{\A/}
19
+ # meta-commands start with /
20
+ case (words = line.split).shift
21
+ when "/root"
22
+ parser.root = words[0] && words[0].to_sym || :definition
23
+ puts "ok"
24
+ else
25
+ puts "Unknown metacommand #{line}, did you mean /root <rule>?"
26
+ end
27
+ statement = nil
28
+ elsif parser.root != :definition or
29
+ line.gsub(/(['"])([^\1\\]|\\.)*\1/,'') =~ /;/
30
+ # After stripping string literals the line contains a ';', it's the last line of the command:
31
+ begin
32
+ result = parser.parse(statement)
33
+ if result
34
+ begin
35
+ p result.value
36
+ rescue => e
37
+ puts e.to_s+":"
38
+ p result # In case the root is changed and there's no value()
39
+ end
40
+ #p parser.definition(result)
41
+ else
42
+ p parser.failure_reason
43
+ end
44
+ rescue => e
45
+ puts e
46
+ puts "\t"+e.backtrace*"\n\t"
47
+ end
48
+ statement = nil
49
+ end
50
+ end
51
+ puts
52
+
@@ -0,0 +1,46 @@
1
+ vocabulary Address;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ City is defined as VariableLengthText(64);
7
+ CompanyName is defined as VariableLengthText();
8
+ FamilyName is defined as VariableLengthText(20);
9
+ GivenNames is defined as VariableLengthText(20);
10
+ Number is defined as VariableLengthText(12);
11
+ Postcode is defined as VariableLengthText();
12
+ StreetLine is defined as VariableLengthText(64);
13
+
14
+ /*
15
+ * Entity Types
16
+ */
17
+ Company is identified by its Name;
18
+
19
+ Family is identified by its Name;
20
+
21
+ Person is identified by Family and GivenNames where
22
+ Person is of one Family,
23
+ Family includes Person,
24
+ Person has one GivenNames;
25
+
26
+ Street is identified by first-StreetLine and second-StreetLine and third-StreetLine where
27
+ Street includes one first-StreetLine,
28
+ Street includes at most one second-StreetLine,
29
+ Street includes at most one third-StreetLine;
30
+
31
+ Address is identified by street-Number and Street and City and Postcode where
32
+ Address is at at most one street-Number,
33
+ Address is at one Street,
34
+ Address is in one City,
35
+ Address is in at most one Postcode,
36
+ Postcode is of Address;
37
+ Company has head office at at most one Address;
38
+ Person lives at at most one Address;
39
+
40
+ /*
41
+ * Constraints:
42
+ */
43
+ Street includes third-StreetLine
44
+ only if Street includes second-StreetLine;
45
+ Street includes second-StreetLine
46
+ only if Street includes first-StreetLine;
@@ -0,0 +1,54 @@
1
+ vocabulary Blog;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ AuthorId is defined as AutoCounter();
7
+ CommentId is defined as AutoCounter();
8
+ Name is defined as VariableLengthText(64);
9
+ Ordinal is defined as UnsignedInteger(32);
10
+ PostId is defined as AutoCounter();
11
+ Style is defined as VariableLengthText(20);
12
+ Text is defined as LargeLengthText();
13
+ TopicId is defined as AutoCounter();
14
+
15
+ /*
16
+ * Entity Types
17
+ */
18
+ Author is identified by its Id;
19
+ author-Name is of at most one Author,
20
+ Author is called one Name;
21
+
22
+ Comment is identified by its Id;
23
+ Author wrote Comment,
24
+ Comment was written by one Author;
25
+
26
+ Content is identified by Style and Text where
27
+ Content is of at most one Style,
28
+ Content has one Text,
29
+ Text is of Content;
30
+ Content provides text of at most one Comment,
31
+ Comment consists of one text-Content;
32
+
33
+ Post is identified by its Id;
34
+ Post was written by one Author;
35
+ Paragraph is where
36
+ Post includes Ordinal paragraph;
37
+ Content is of at most one Paragraph,
38
+ Paragraph contains one Content;
39
+ Paragraph has Comment,
40
+ Comment is on one Paragraph;
41
+
42
+ Topic is identified by its Id;
43
+ Post belongs to one Topic,
44
+ Topic contains Post;
45
+ Topic belongs to at most one parent-Topic [acyclic];
46
+ Topic is called one topic-Name,
47
+ Name is of at most one Topic;
48
+
49
+ /*
50
+ * Constraints:
51
+ */
52
+ for each Content exactly one of these holds:
53
+ Content provides text of Comment,
54
+ Content is of Paragraph;
@@ -0,0 +1,51 @@
1
+ vocabulary CompanyDirector;
2
+
3
+ /*
4
+ * Value Types
5
+ */
6
+ CompanyName is defined as VariableLengthText(48);
7
+ EmployeeNr is defined as SignedInteger(32);
8
+ Name is defined as VariableLengthText(48);
9
+
10
+ /*
11
+ * Entity Types
12
+ */
13
+ Company is identified by its Name where
14
+ Company is called CompanyName;
15
+ Company is listed;
16
+
17
+ Meeting is identified by Date and Meeting is board meeting and Company where
18
+ Meeting is held on one Date,
19
+ Meeting is board meeting,
20
+ Company held Meeting,
21
+ Meeting is held by one Company;
22
+
23
+ Person is identified by given-Name and family-Name where
24
+ Person has one given-Name,
25
+ given-Name is of Person,
26
+ family-Name is of Person,
27
+ Person is called at most one family-Name;
28
+ Person was born on at most one birth-Date;
29
+ Attendance is where
30
+ Person (as Attendee) attended Meeting,
31
+ Meeting was attended by Attendee;
32
+ Directorship is where
33
+ Person (as Director) directs Company,
34
+ Company is directed by at least one Director;
35
+ Directorship began on one appointment-Date;
36
+
37
+ Employee is a kind of Person identified by its Nr;
38
+ Employee works at one Company,
39
+ Company employs Employee;
40
+
41
+ Manager is a kind of Employee;
42
+ Employee is supervised by at most one Manager [acyclic],
43
+ Manager supervises Employee;
44
+ Manager is ceo;
45
+
46
+ /*
47
+ * Constraints:
48
+ */
49
+ for each Employee exactly one of these holds:
50
+ that Employee is ceo,
51
+ that Employee is supervised by some Manager;