mexico 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.document +5 -0
- data/.gitmodules +3 -0
- data/.project +14 -0
- data/.rspec +2 -0
- data/Gemfile +31 -0
- data/LICENSE.txt +165 -0
- data/README.md +116 -0
- data/Rakefile +66 -0
- data/VERSION +1 -0
- data/assets/TESTCORPUS/Corpus.xml +26 -0
- data/assets/fiesta/b6/layer_connectors.fst +16 -0
- data/assets/fiesta/b6/match_jones_161_CM_neu_checked.parsed.xml +1225 -0
- data/assets/fiesta/elan/ElanFileFormat.eaf +76 -0
- data/assets/fiesta/elan/ElanFileFormat.pfsx +8 -0
- data/assets/fiesta/elan/ElanFileFormatComplexInterLayerLinks.eaf +107 -0
- data/assets/fiesta/elan/reflinks_example.eaf +270 -0
- data/assets/fiesta/elan/test_all_interlayerrelations.fst +43 -0
- data/assets/fiesta/head/head.fst +24 -0
- data/assets/fiesta/praat/mexico.ShortTextGrid +81 -0
- data/assets/fiesta/praat/mexico.TextGrid +104 -0
- data/assets/helpers/collection_ref_handler.rb +29 -0
- data/assets/helpers/id_ref_handler.rb +29 -0
- data/assets/helpers/roxml_attribute_handler.rb +57 -0
- data/assets/out_only/construct_and_write_spec.toe +99 -0
- data/assets/spec.html +554 -0
- data/bin/mexico +5 -0
- data/features/mexico.feature +9 -0
- data/features/step_definitions/mexico_steps.rb +0 -0
- data/features/support/env.rb +15 -0
- data/info/releasenotes/0.0.1.md +5 -0
- data/info/releasenotes/0.0.2.md +5 -0
- data/info/releasenotes/0.0.3.md +5 -0
- data/info/releasenotes/0.0.4.md +5 -0
- data/info/releasenotes/0.0.5.md +8 -0
- data/info/releasenotes/0.0.6.md +3 -0
- data/info/releasenotes/0.0.7.md +4 -0
- data/info/releasenotes/0.0.8.md +9 -0
- data/info/releasenotes/0.0.9.md +7 -0
- data/lib/mexico/cmd.rb +210 -0
- data/lib/mexico/constants.rb +82 -0
- data/lib/mexico/constraints/constraint.rb +85 -0
- data/lib/mexico/constraints/fiesta_constraints.rb +209 -0
- data/lib/mexico/constraints.rb +27 -0
- data/lib/mexico/core/corpus_core.rb +39 -0
- data/lib/mexico/core/design_core.rb +31 -0
- data/lib/mexico/core/media_type.rb +61 -0
- data/lib/mexico/core.rb +36 -0
- data/lib/mexico/fiesta/interfaces/b6_chat_game_interface.rb +222 -0
- data/lib/mexico/fiesta/interfaces/elan_interface.rb +143 -0
- data/lib/mexico/fiesta/interfaces/short_text_grid_interface.rb +99 -0
- data/lib/mexico/fiesta/interfaces/text_grid_interface.rb +103 -0
- data/lib/mexico/fiesta/interfaces.rb +31 -0
- data/lib/mexico/fiesta.rb +27 -0
- data/lib/mexico/file_system/bound_to_corpus.rb +37 -0
- data/lib/mexico/file_system/corpus.rb +207 -0
- data/lib/mexico/file_system/data.rb +96 -0
- data/lib/mexico/file_system/design.rb +75 -0
- data/lib/mexico/file_system/design_component.rb +78 -0
- data/lib/mexico/file_system/entry.rb +59 -0
- data/lib/mexico/file_system/fiesta_document.rb +344 -0
- data/lib/mexico/file_system/fiesta_map.rb +112 -0
- data/lib/mexico/file_system/head.rb +33 -0
- data/lib/mexico/file_system/id_ref.rb +46 -0
- data/lib/mexico/file_system/implicit_item_link.rb +19 -0
- data/lib/mexico/file_system/interval_link.rb +84 -0
- data/lib/mexico/file_system/item.rb +166 -0
- data/lib/mexico/file_system/item_link.rb +98 -0
- data/lib/mexico/file_system/item_links_proxy.rb +13 -0
- data/lib/mexico/file_system/layer.rb +89 -0
- data/lib/mexico/file_system/layer_connector.rb +74 -0
- data/lib/mexico/file_system/layer_link.rb +75 -0
- data/lib/mexico/file_system/local_file.rb +101 -0
- data/lib/mexico/file_system/participant.rb +69 -0
- data/lib/mexico/file_system/participant_role.rb +43 -0
- data/lib/mexico/file_system/point_link.rb +79 -0
- data/lib/mexico/file_system/property.rb +35 -0
- data/lib/mexico/file_system/property_map.rb +37 -0
- data/lib/mexico/file_system/resource.rb +174 -0
- data/lib/mexico/file_system/scale.rb +125 -0
- data/lib/mexico/file_system/section.rb +41 -0
- data/lib/mexico/file_system/static_collection_ref.rb +64 -0
- data/lib/mexico/file_system/template.rb +23 -0
- data/lib/mexico/file_system/trial.rb +87 -0
- data/lib/mexico/file_system/url.rb +65 -0
- data/lib/mexico/file_system.rb +62 -0
- data/lib/mexico/not_yet_implemented_error.rb +28 -0
- data/lib/mexico/util/fancy_container.rb +57 -0
- data/lib/mexico/util.rb +51 -0
- data/lib/mexico.rb +36 -0
- data/spec/constraints/constraints_spec.rb +306 -0
- data/spec/core/media_type_spec.rb +50 -0
- data/spec/fiesta/b6_spec.rb +43 -0
- data/spec/fiesta/elan_spec.rb +43 -0
- data/spec/fiesta/head_spec.rb +54 -0
- data/spec/fiesta/praat_spec.rb +54 -0
- data/spec/fiesta/read_spec.rb +76 -0
- data/spec/file_system_based/better_collection_spec.rb +142 -0
- data/spec/file_system_based/corpus_spec.rb +194 -0
- data/spec/file_system_based/design_spec.rb +100 -0
- data/spec/file_system_based/inter_links_spec.rb +100 -0
- data/spec/file_system_based/item_links_spec.rb +76 -0
- data/spec/file_system_based/rdf_spec.rb +177 -0
- data/spec/file_system_based/resource_spec.rb +111 -0
- data/spec/file_system_based/trial_spec.rb +129 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/toe/construct_and_write_spec.rb +82 -0
- data/spec/toe/construction_spec.rb +110 -0
- data/spec/toe/item_spec.rb +58 -0
- data/spec/toe/layer_spec.rb +63 -0
- data/spec/toe/scale_spec.rb +89 -0
- data/spec/toe/toe_document_spec.rb +39 -0
- data/test/helper.rb +19 -0
- data/test/test_mexico.rb +7 -0
- metadata +357 -0
@@ -0,0 +1,7 @@
|
|
1
|
+
## Release notes for version 0.0.9
|
2
|
+
|
3
|
+
+ **#94**: Added implementation of constraints, and specs and assets for testing or debugging constraints.
|
4
|
+
+ **#150**: Created a first version of the import and export interface.
|
5
|
+
+ **#152**: Importers for Praat TextGrid and ShortTextGrid formats are now integrated.
|
6
|
+
+ **#153**: Completed first implementation of ELAN EAF import (still incomplete).
|
7
|
+
+ **#215**: The library now has flexible accessors for scales, layers, and items.
|
data/lib/mexico/cmd.rb
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
# This file is part of the MExiCo gem.
|
2
|
+
# Copyright (c) 2012-2014 Peter Menke, SFB 673, Universität Bielefeld
|
3
|
+
# http://www.sfb673.org
|
4
|
+
#
|
5
|
+
# MExiCo is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Lesser General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of
|
8
|
+
# the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# MExiCo is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with MExiCo. If not, see
|
17
|
+
# <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
require 'optparse'
|
20
|
+
require 'colorize'
|
21
|
+
|
22
|
+
# This class serves as the interface for the MExiCo executable. All subcommands
|
23
|
+
# of the MExiCo executable are bound to class methods of the +Cmd+ class.
|
24
|
+
class Mexico::Cmd
|
25
|
+
|
26
|
+
# Array of names of currently supported subcommands.
|
27
|
+
SUBCOMMANDS = %w(help info init status)
|
28
|
+
|
29
|
+
# Hash of descriptions for the currently supported subcommands.
|
30
|
+
SUBCOMMAND_DESCRIPTIONS = {}
|
31
|
+
|
32
|
+
SUBCOMMAND_DESCRIPTIONS["help"] = "Display helpful information and exit."
|
33
|
+
SUBCOMMAND_DESCRIPTIONS["info"] = "Display information about the corpus the current folder belongs to."
|
34
|
+
SUBCOMMAND_DESCRIPTIONS["init"] = "Create corpus structure files in an existing or new folder."
|
35
|
+
SUBCOMMAND_DESCRIPTIONS["status"] = "Show status info of file linkage and format conversion."
|
36
|
+
|
37
|
+
# the default banner to be displayed on the console when asked for how to use the executable.
|
38
|
+
DEFAULT_BANNER = "Usage: mexico [subcommand] [options]"
|
39
|
+
|
40
|
+
# Hash of option parser objects for the currently supported subcommand.s
|
41
|
+
OPTION_PARSERS = {}
|
42
|
+
|
43
|
+
OPTION_PARSERS["help"] = OptionParser.new do |opts|
|
44
|
+
end
|
45
|
+
|
46
|
+
OPTION_PARSERS["info"] = OptionParser.new do |opts|
|
47
|
+
opts.banner = "Usage: mexico info [options]"
|
48
|
+
opts.on("-p", "--path PATH", "Look for corpus manifest at PATH") do |p|
|
49
|
+
@@options[:path] = p
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
OPTION_PARSERS["init"] = OptionParser.new do |opts|
|
54
|
+
opts.banner = "Usage: mexico init [options]"
|
55
|
+
opts.on("-p", "--path PATH", "Create corpus folder and manifest at PATH") do |p|
|
56
|
+
@@options[:path] = p
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
OPTION_PARSERS.values.each do |p|
|
61
|
+
p.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
62
|
+
@@options[:verbose] = v
|
63
|
+
end
|
64
|
+
p.on("-d", "--[no-]debug", "Turn on debugging output") do |d|
|
65
|
+
@@options[:debug] = d
|
66
|
+
end
|
67
|
+
p.separator ""
|
68
|
+
p.separator "Available subcommands are"
|
69
|
+
p.separator "-------------------------"
|
70
|
+
SUBCOMMANDS.each do |sc|
|
71
|
+
p.separator "%8s - %s" % [sc, SUBCOMMAND_DESCRIPTIONS[sc]]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
@@options = {}
|
76
|
+
|
77
|
+
# Helper method that writes an informative verbose message to the console
|
78
|
+
# if the +verbose+ parameter was given on the command line.
|
79
|
+
# @param (String) message A verbose message to be sent to stdout.
|
80
|
+
# @return (void)
|
81
|
+
def self.verbose(message)
|
82
|
+
puts "VERBOSE: #{message}".cyan if @@options[:verbose]
|
83
|
+
end
|
84
|
+
|
85
|
+
# Helper method that writes debugging information (typically in critical
|
86
|
+
# and error cases) to the console
|
87
|
+
# if the +debug+ parameter was given on the command line.
|
88
|
+
# @param (String) message A debugging message to be sent to stdout.
|
89
|
+
# @return (void)
|
90
|
+
def self.debug(message)
|
91
|
+
puts "DEBUG: #{message}".magenta if @@options[:debug]
|
92
|
+
end
|
93
|
+
|
94
|
+
# helper method that creates a human-readable file size representation
|
95
|
+
# (suffixed with "KB", "MB", "GB", etc.).
|
96
|
+
# @param (Number) number the number to be formatted
|
97
|
+
# @return (String) a human-readable file size representation of that number
|
98
|
+
def self.humanize(number)
|
99
|
+
prefs = %w(T G M K)
|
100
|
+
display_number = number.to_f
|
101
|
+
unit = ""
|
102
|
+
while(display_number>1000 && !prefs.empty?)
|
103
|
+
display_number = display_number / 1024.0
|
104
|
+
unit = prefs.pop()
|
105
|
+
end
|
106
|
+
return "%.1f %sB" % [display_number, unit]
|
107
|
+
end
|
108
|
+
|
109
|
+
# The core method that is called when the executable runs.
|
110
|
+
# @param (Collection) arx a list of the command line parameters.
|
111
|
+
# @return (void) Should not return anything since {System::exit}
|
112
|
+
# is usually called at some point in this method.
|
113
|
+
def self.run!(arx)
|
114
|
+
argsize = ARGV.size
|
115
|
+
if argsize>0
|
116
|
+
subcommand = ARGV.shift
|
117
|
+
|
118
|
+
if SUBCOMMANDS.include?(subcommand)
|
119
|
+
# ok, command is known
|
120
|
+
if argsize>1
|
121
|
+
OPTION_PARSERS[subcommand].parse!
|
122
|
+
else
|
123
|
+
# no more commands.
|
124
|
+
end
|
125
|
+
self.verbose "Verbose mode. MExiCo displays more info on what it does in cyan."
|
126
|
+
self.debug "Debug mode. MExiCo displays lots of internal information in magenta."
|
127
|
+
self.verbose "MExiCo #{subcommand}"
|
128
|
+
Mexico::Cmd.send(subcommand, @@options)
|
129
|
+
else
|
130
|
+
# break: command not known
|
131
|
+
OPTION_PARSERS['help'].parse!
|
132
|
+
self.help(@@options)
|
133
|
+
end
|
134
|
+
self.debug("Detected arguments: %s" % @@options)
|
135
|
+
unless ARGV.empty?
|
136
|
+
self.debug("Leftover arguments: %s" % ARGV)
|
137
|
+
end
|
138
|
+
self.debug("Subcommand: %s" % subcommand)
|
139
|
+
else
|
140
|
+
puts option_parser
|
141
|
+
exit(1)
|
142
|
+
end
|
143
|
+
exit(0)
|
144
|
+
end
|
145
|
+
|
146
|
+
# This method handles the *help* subcommand.
|
147
|
+
# @param (Hash) options a hash of raw options from the command line.
|
148
|
+
# It does nothing but output usage information to the console and quit.
|
149
|
+
# @return nil
|
150
|
+
def self.help(options)
|
151
|
+
puts "Help".magenta
|
152
|
+
puts OPTION_PARSERS['help']
|
153
|
+
exit(0)
|
154
|
+
end
|
155
|
+
|
156
|
+
# This method handles the *info* subcommand. It prints out basic information
|
157
|
+
# about an existing corpus.
|
158
|
+
# @param (Hash) options a hash of raw options from the command line.
|
159
|
+
# @return nil
|
160
|
+
def self.info(options)
|
161
|
+
# check if current folder is corpus folder
|
162
|
+
current_folder = File.dirname(__FILE__)
|
163
|
+
if options.has_key?(:path)
|
164
|
+
current_folder = options[:path]
|
165
|
+
end
|
166
|
+
corpus_manifest = File.join(current_folder,"Corpus.xml")
|
167
|
+
if File.exists?(corpus_manifest)
|
168
|
+
self.verbose "Current Directory '#{current_folder}' is a corpus folder, opening."
|
169
|
+
# open corpus manifest, analyse
|
170
|
+
corpus = Mexico::FileSystem::Corpus.open(current_folder)
|
171
|
+
puts ""
|
172
|
+
puts "-"*72
|
173
|
+
puts "%15s : %-50s" % ["Identifier", corpus.identifier]
|
174
|
+
puts "%15s : %-50s" % ["Name", corpus.name]
|
175
|
+
displ_description = ""
|
176
|
+
displ_description = corpus.description.split("\n").first unless corpus.description.blank?
|
177
|
+
displ_description = displ_description.slice(0,47)+" ..." unless displ_description.length<47
|
178
|
+
puts "%15s : %-50s" % ["Description", displ_description]
|
179
|
+
puts "-"*72
|
180
|
+
puts "%15s : %-50s" % ["Designs", corpus.designs.size]
|
181
|
+
puts "%15s : %-50s" % ["Trials", corpus.trials.size]
|
182
|
+
puts "%15s : %-50s" % ["Resources", corpus.resources.size]
|
183
|
+
puts "%15s : %-50s" % ["Local Files", corpus.resources.collect{|i| i.local_files}.flatten.size]
|
184
|
+
puts "%15s : %-50s" % ["Used Disk Space", humanize(corpus.complete_file_size)]
|
185
|
+
puts "-"*72
|
186
|
+
puts ""
|
187
|
+
else
|
188
|
+
puts "Error: No corpus manifest folder found in '#{current_folder}'.".red
|
189
|
+
puts "Seems like no corpus has been initialized here.".red
|
190
|
+
exit(1)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# This method handles the *init* subcommand. It can create the necessary structures and files
|
195
|
+
# for a new corpus folder.
|
196
|
+
# @param (Hash) options a hash of raw options from the command line.
|
197
|
+
# @return nil
|
198
|
+
def self.init(options)
|
199
|
+
puts "The 'init' subcommand is not yet implemented."
|
200
|
+
exit(0)
|
201
|
+
end
|
202
|
+
|
203
|
+
# This method handles the *status* subcommand. It outputs various pieces of information about
|
204
|
+
# the corpus, its linkage to a remote repository, untracked files, etc.
|
205
|
+
def self.status(options)
|
206
|
+
puts "The 'status' subcommand is not yet implemented."
|
207
|
+
exit(0)
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# This file is part of the MExiCo gem.
|
2
|
+
# Copyright (c) 2012-2014 Peter Menke, SFB 673, Universität Bielefeld
|
3
|
+
# http://www.sfb673.org
|
4
|
+
#
|
5
|
+
# MExiCo is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Lesser General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of
|
8
|
+
# the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# MExiCo is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with MExiCo. If not, see
|
17
|
+
# <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
# This module aggregates all constant (type-level) objects that
|
20
|
+
# are needed for corpus management.
|
21
|
+
module Mexico::Constants
|
22
|
+
|
23
|
+
# This module lists all participant roles
|
24
|
+
# that are part of the current MExiCo model.
|
25
|
+
module ParticipantRoles
|
26
|
+
|
27
|
+
# A naive participant who does not have additional
|
28
|
+
# background information about the experiment
|
29
|
+
NAIVE = Mexico::FileSystem::ParticipantRole.new :identifier =>'naive', :name => 'Naive Participant'
|
30
|
+
|
31
|
+
# A participant who has been instructed and informed
|
32
|
+
# about the experiment in at least one aspect, and
|
33
|
+
# who pretends to be naive to other participants
|
34
|
+
CONFEDERATE = Mexico::FileSystem::ParticipantRole.new :identifier =>'confederate', :name => 'Confederate'
|
35
|
+
|
36
|
+
# container for all other roles
|
37
|
+
OTHER = Mexico::FileSystem::ParticipantRole.new :identifier =>'other-participant-role', :name => 'Other'
|
38
|
+
|
39
|
+
# A collection of all participant roles currently predefined.
|
40
|
+
ALL = Array.new
|
41
|
+
ALL << ::Mexico::Constants::ParticipantRoles::NAIVE
|
42
|
+
ALL << ::Mexico::Constants::ParticipantRoles::CONFEDERATE
|
43
|
+
|
44
|
+
# retrieves a participant role object by its key.
|
45
|
+
# @param [String] key The key of the needed participant role.
|
46
|
+
# @return [Mexico::FileSystem::ParticipantRole,nil] the participant role object, or nil, if no object was found.
|
47
|
+
def self.get(key)
|
48
|
+
::Mexico::Constants::ParticipantRoles::ALL.first{ |x| x.identifier==key}
|
49
|
+
end
|
50
|
+
|
51
|
+
# checks for the existence of a predefined participant role object.
|
52
|
+
# @param [String] key The key of the needed participant role.
|
53
|
+
# @return [true,false] true iff such a participant role object exists, false otherwise.
|
54
|
+
def self.has?(key)
|
55
|
+
::Mexico::Constants::ParticipantRoles::ALL.select{ |x| x.identifier==key}.size>0
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
# Scale modes are categories of scales based on the publication by S. S. Stevens
|
61
|
+
# (Stevens, S. S. (1946). On the Theory of Scales of Measurement. Science, 103(2684), pp.677-680).
|
62
|
+
# scales have different properties and allow different operations depending on their
|
63
|
+
# level.
|
64
|
+
module ScaleModes
|
65
|
+
|
66
|
+
# The nominal scale is the simplest scale mode. It makes equality / inequality operations available.
|
67
|
+
NOMINAL = "nominal"
|
68
|
+
|
69
|
+
# The ordinal scale mode is the next mode after the nominal mode. Besides all operations of the
|
70
|
+
# nominal mode, it makes an ordering operations and comparisons available.
|
71
|
+
ORDINAL = "ordinal"
|
72
|
+
|
73
|
+
# The cardinal scale mode is the next mode after the ordinal mode. Besides all operations of the
|
74
|
+
# ordinal mode, it makes operations and comparisons based on distances or metrics available.
|
75
|
+
CARDINAL = "cardinal"
|
76
|
+
|
77
|
+
# The ratio scale mode is the next mode after the cardinal mode. Besides all operations of the
|
78
|
+
# cardinal mode, it makes operations and comparisons based on a zero point available.
|
79
|
+
RATIO = "ratio"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is part of the MExiCo gem.
|
3
|
+
# Copyright (c) 2012-2014 Peter Menke, SFB 673, Universität Bielefeld
|
4
|
+
# http://www.sfb673.org
|
5
|
+
#
|
6
|
+
# MExiCo is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Lesser General Public License as
|
8
|
+
# published by the Free Software Foundation, either version 3 of
|
9
|
+
# the License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# MExiCo is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with MExiCo. If not, see
|
18
|
+
# <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
# This class defines a constraint used for type-validating an object.
|
21
|
+
|
22
|
+
class Mexico::Constraints::Constraint
|
23
|
+
|
24
|
+
|
25
|
+
def self.create(key, config={}, &evaluator)
|
26
|
+
constraint = self.new(key, evaluator)
|
27
|
+
constraint.add_parent(config[:parent]) if config.has_key?(:parent)
|
28
|
+
config[:parents].each{ |p| constraint.add_parent(p) } if config.has_key?(:parents)
|
29
|
+
|
30
|
+
@@REGISTERED_CONSTRAINTS = {} unless defined?(@@REGISTERED_CONSTRAINTS)
|
31
|
+
@@REGISTERED_CONSTRAINTS[key] = constraint
|
32
|
+
|
33
|
+
return constraint
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.knows?(key)
|
37
|
+
defined?(@@REGISTERED_CONSTRAINTS) && @@REGISTERED_CONSTRAINTS.has_key?(key)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.get(key)
|
41
|
+
defined?(@@REGISTERED_CONSTRAINTS) && @@REGISTERED_CONSTRAINTS[key]
|
42
|
+
end
|
43
|
+
|
44
|
+
def evaluate(document)
|
45
|
+
self.evaluator.call(document)
|
46
|
+
end
|
47
|
+
|
48
|
+
def initialize(key, evaluator)
|
49
|
+
@key = key
|
50
|
+
@evaluator = evaluator
|
51
|
+
@parents = []
|
52
|
+
@children = []
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_parent(parent)
|
56
|
+
internal_add_parent(parent)
|
57
|
+
parent.internal_add_child(self)
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_child(child)
|
61
|
+
internal_add_child(child)
|
62
|
+
child.internal_add_parent(self)
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
attr_reader :evaluator
|
67
|
+
attr_accessor :key
|
68
|
+
attr_accessor :parents
|
69
|
+
attr_accessor :children
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
attr_writer :evaluator
|
74
|
+
|
75
|
+
protected
|
76
|
+
|
77
|
+
def internal_add_parent(parent)
|
78
|
+
@parents << parent
|
79
|
+
end
|
80
|
+
|
81
|
+
def internal_add_child(child)
|
82
|
+
@children << child
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is part of the MExiCo gem.
|
3
|
+
# Copyright (c) 2012-2014 Peter Menke, SFB 673, Universität Bielefeld
|
4
|
+
# http://www.sfb673.org
|
5
|
+
#
|
6
|
+
# MExiCo is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Lesser General Public License as
|
8
|
+
# published by the Free Software Foundation, either version 3 of
|
9
|
+
# the License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# MExiCo is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
17
|
+
# License along with MExiCo. If not, see
|
18
|
+
# <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
|
21
|
+
module Mexico::Constraints::FiestaConstraints
|
22
|
+
|
23
|
+
include Mexico::Constraints
|
24
|
+
|
25
|
+
TOP = Constraint.create('TOP') do |doc|
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
30
|
+
# Scale-related constraints
|
31
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
32
|
+
|
33
|
+
SCALES_TOP = Constraint.create('SCALES_TOP', parent: TOP) do |doc|
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
SCALES_LTE_3 = Constraint.create('SCALES_LTE_3', parent: SCALES_TOP) do |doc|
|
38
|
+
doc.scales.size <= 3
|
39
|
+
end
|
40
|
+
|
41
|
+
SCALES_LTE_2 = Constraint.create('SCALES_LTE_2', parent: SCALES_LTE_3) do |doc|
|
42
|
+
doc.scales.size <= 2
|
43
|
+
end
|
44
|
+
|
45
|
+
SCALES_LTE_1 = Constraint.create('SCALES_LTE_1', parent: SCALES_LTE_2) do |doc|
|
46
|
+
doc.scales.size <= 1
|
47
|
+
end
|
48
|
+
|
49
|
+
SCALES_GTE_1 = Constraint.create('SCALES_GTE_1', parent: SCALES_TOP) do |doc|
|
50
|
+
doc.scales.size >= 1
|
51
|
+
end
|
52
|
+
|
53
|
+
SCALES_GTE_2 = Constraint.create('SCALES_GTE_2', parent: SCALES_GTE_1) do |doc|
|
54
|
+
doc.scales.size >= 2
|
55
|
+
end
|
56
|
+
|
57
|
+
SCALES_GTE_3 = Constraint.create('SCALES_GTE_3', parent: SCALES_GTE_2) do |doc|
|
58
|
+
doc.scales.size >= 3
|
59
|
+
end
|
60
|
+
|
61
|
+
SCALES_GTE_4 = Constraint.create('SCALES_GTE_4', parent: SCALES_GTE_3) do |doc|
|
62
|
+
doc.scales.size >= 4
|
63
|
+
end
|
64
|
+
|
65
|
+
SCALES_HAS_1_TIMELINE = Constraint.create('SCALES_HAS_1_TIMELINE', parent: SCALES_GTE_1) do |doc|
|
66
|
+
SCALES_GTE_1.evaluate(doc) && doc.scales[0].is_timeline?
|
67
|
+
end
|
68
|
+
|
69
|
+
SCALES_HAS_2_TIMELINES = Constraint.create('SCALES_HAS_2_TIMELINES', parent: SCALES_GTE_2) do |doc|
|
70
|
+
SCALES_GTE_2.evaluate(doc) && doc.scales[0].is_timeline? && doc.scales[1].is_timeline?
|
71
|
+
end
|
72
|
+
|
73
|
+
SCALES_EX_1_TIMELINE = Constraint.create('SCALES_EX_1_TIMELINE', parents: [SCALES_HAS_1_TIMELINE,SCALES_LTE_1]) do |doc|
|
74
|
+
SCALES_HAS_1_TIMELINE.evaluate(doc) && SCALES_LTE_1.evaluate(doc)
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
79
|
+
# Constraints related to layer structures
|
80
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
81
|
+
|
82
|
+
LAYERS_TOP = Constraint.create('LAYERS_TOP', parent: TOP) do |doc|
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
LAYERS_GRAPH = Constraint.create('LAYERS_GRAPH', parent: LAYERS_TOP) do |doc|
|
87
|
+
true
|
88
|
+
end
|
89
|
+
|
90
|
+
LAYERS_DAG = Constraint.create('LAYERS_DAG', parent: LAYERS_GRAPH) do |doc|
|
91
|
+
doc.layers_form_a_dag?
|
92
|
+
end
|
93
|
+
|
94
|
+
LAYERS_CDAG = Constraint.create('LAYERS_CDAG', parent: LAYERS_DAG) do |doc|
|
95
|
+
doc.layers_form_a_cdag?
|
96
|
+
end
|
97
|
+
|
98
|
+
LAYERS_FOREST = Constraint.create('LAYERS_FOREST', parent: LAYERS_DAG) do |doc|
|
99
|
+
doc.layers_form_a_forest?
|
100
|
+
end
|
101
|
+
|
102
|
+
LAYERS_TREE = Constraint.create('LAYERS_TREE', parents: [LAYERS_CDAG,LAYERS_FOREST]) do |doc|
|
103
|
+
doc.layers_form_a_tree?
|
104
|
+
end
|
105
|
+
|
106
|
+
LAYERS_EDGELESS = Constraint.create('LAYERS_EDGELESS', parent: LAYERS_FOREST) do |doc|
|
107
|
+
doc.layers_form_an_edgeless_graph?
|
108
|
+
end
|
109
|
+
|
110
|
+
LAYERS_EMPTY = Constraint.create('LAYERS_EMPTY', parent: LAYERS_GRAPH) do |doc|
|
111
|
+
doc.layers_form_an_empty_graph?
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
116
|
+
# Constraints related to intra-layer structures
|
117
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
118
|
+
|
119
|
+
INTRALAYER_TOP = Constraint.create('INTRALAYER_TOP', parent: TOP) do |doc|
|
120
|
+
true
|
121
|
+
end
|
122
|
+
|
123
|
+
INTRALAYER_GRAPH_ALL = Constraint.create('INTRALAYER_GRAPH', parent: INTRALAYER_TOP) do |doc|
|
124
|
+
true
|
125
|
+
end
|
126
|
+
|
127
|
+
INTRALAYER_FOREST_ALL = Constraint.create('INTRALAYER_FOREST_ALL', parent: INTRALAYER_GRAPH_ALL) do |doc|
|
128
|
+
boolean_result = true
|
129
|
+
doc.layers.each do |layer|
|
130
|
+
boolean_result = boolean_result && layer.items_form_a_forest?
|
131
|
+
end
|
132
|
+
boolean_result
|
133
|
+
end
|
134
|
+
|
135
|
+
# This one is actually used.
|
136
|
+
INTRALAYER_EDGELESS_ALL = Constraint.create('INTRALAYER_EDGELESS_ALL', parent: INTRALAYER_FOREST_ALL) do |doc|
|
137
|
+
boolean_result = true
|
138
|
+
doc.layers.each do |layer|
|
139
|
+
boolean_result = boolean_result && layer.items_form_an_edgeless_graph?
|
140
|
+
end
|
141
|
+
boolean_result
|
142
|
+
end
|
143
|
+
|
144
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
145
|
+
# Constraints related to inter-layer structures
|
146
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
147
|
+
|
148
|
+
# needed: calculation of the inter-layer-graph
|
149
|
+
# take all nodes from layer 1, all nodes from layer 2
|
150
|
+
# find all item links that have a l1 node as source and an l2 node as target
|
151
|
+
|
152
|
+
INTERLAYER_TOP = Constraint.create('INTERLAYER_TOP', parent: TOP) do |doc|
|
153
|
+
true
|
154
|
+
end
|
155
|
+
|
156
|
+
INTERLAYER_SOURCE_LTE_1 = Constraint.create('INTERLAYER_SOURCE_LTE_1', parent: INTERLAYER_TOP) do |doc|
|
157
|
+
puts doc.inter_layer_source_cardinality
|
158
|
+
doc.inter_layer_source_cardinality <= 1
|
159
|
+
end
|
160
|
+
|
161
|
+
INTERLAYER_SOURCE_0 = Constraint.create('INTERLAYER_SOURCE_0', parent: INTERLAYER_SOURCE_LTE_1) do |doc|
|
162
|
+
puts doc.inter_layer_source_cardinality
|
163
|
+
doc.inter_layer_source_cardinality == 0
|
164
|
+
end
|
165
|
+
|
166
|
+
INTERLAYER_SINK_LTE_1 = Constraint.create('INTERLAYER_SINK_LTE_1', parent: INTERLAYER_TOP) do |doc|
|
167
|
+
puts doc.inter_layer_sink_cardinality
|
168
|
+
doc.inter_layer_sink_cardinality <= 1
|
169
|
+
end
|
170
|
+
|
171
|
+
INTERLAYER_SINK_0 = Constraint.create('INTERLAYER_SINK_0', parent: INTERLAYER_SINK_LTE_1) do |doc|
|
172
|
+
puts doc.inter_layer_sink_cardinality
|
173
|
+
oc.inter_layer_sink_cardinality == 0
|
174
|
+
end
|
175
|
+
|
176
|
+
INTERLAYER_1_TO_N = Constraint.create('INTERLAYER_1_TO_N', parents: [INTERLAYER_SOURCE_LTE_1]) do |doc|
|
177
|
+
INTERLAYER_SOURCE_LTE_1.evaluate(doc)
|
178
|
+
end
|
179
|
+
|
180
|
+
INTERLAYER_N_TO_1 = Constraint.create('INTERLAYER_N_TO_1', parents: [INTERLAYER_SINK_LTE_1]) do |doc|
|
181
|
+
INTERLAYER_SINK_LTE_1.evaluate(doc)
|
182
|
+
end
|
183
|
+
|
184
|
+
INTERLAYER_1_TO_1 = Constraint.create('INTERLAYER_1_TO_1', parents: [INTERLAYER_1_TO_N, INTERLAYER_N_TO_1]) do |doc|
|
185
|
+
INTERLAYER_1_TO_N.evaluate(doc) && INTERLAYER_N_TO_1.evaluate(doc)
|
186
|
+
end
|
187
|
+
|
188
|
+
INTERLAYER_EDGELESS = Constraint.create('INTERLAYER_EDGELESS', parents: [INTERLAYER_SOURCE_0,INTERLAYER_SINK_0]) do |doc|
|
189
|
+
INTERLAYER_SOURCE_0.evaluate(doc) && INTERLAYER_SINK_0.evaluate(doc)
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
194
|
+
# Constraints related values
|
195
|
+
# # # # # # # # # # # # # # # # # # # # # # # # # # #
|
196
|
+
|
197
|
+
VALUES_TOP = Constraint.create('VALUES_TOP', parent: TOP) do |doc|
|
198
|
+
true
|
199
|
+
end
|
200
|
+
|
201
|
+
VALUES_STRINGS_ONLY = Constraint.create('VALUES_STRINGS_ONLY', parent: VALUES_TOP) do |doc|
|
202
|
+
doc.items.collect{|i| i.data }.all?{|d| d.is_string?}
|
203
|
+
end
|
204
|
+
|
205
|
+
VALUES_MAPS_ONLY = Constraint.create('VALUES_MAPS_ONLY', parent: VALUES_TOP) do |doc|
|
206
|
+
doc.items.collect{|i| i.data }.all?{|d| d.is_map?}
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# This file is part of the MExiCo gem.
|
2
|
+
# Copyright (c) 2012-2014 Peter Menke, SFB 673, Universität Bielefeld
|
3
|
+
# http://www.sfb673.org
|
4
|
+
#
|
5
|
+
# MExiCo is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Lesser General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of
|
8
|
+
# the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# MExiCo is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with MExiCo. If not, see
|
17
|
+
# <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
# This module aggregates all constant (type-level) objects that
|
20
|
+
# are needed for corpus management.
|
21
|
+
|
22
|
+
module Mexico::Constraints
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'mexico/constraints/constraint.rb'
|
27
|
+
require 'mexico/constraints/fiesta_constraints.rb'
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# This file is part of the MExiCo gem.
|
2
|
+
# Copyright (c) 2012-2014 Peter Menke, SFB 673, Universität Bielefeld
|
3
|
+
# http://www.sfb673.org
|
4
|
+
#
|
5
|
+
# MExiCo is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Lesser General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of
|
8
|
+
# the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# MExiCo is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with MExiCo. If not, see
|
17
|
+
# <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
# The Corpus core module contains methods for implementations of the
|
20
|
+
# corpus class that are independent of the implementation.
|
21
|
+
module Mexico::Core::CorpusCore
|
22
|
+
|
23
|
+
#def included(x)
|
24
|
+
# puts "CorpusCore is now included in #{x}."
|
25
|
+
#end
|
26
|
+
|
27
|
+
#def extended(x)
|
28
|
+
# puts "CorpusCore now extends #{x}."
|
29
|
+
#end
|
30
|
+
|
31
|
+
# simple test method that can be called to see whether the module
|
32
|
+
# was included successfully
|
33
|
+
def core_included?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# This file is part of the MExiCo gem.
|
2
|
+
# Copyright (c) 2012-2014 Peter Menke, SFB 673, Universität Bielefeld
|
3
|
+
# http://www.sfb673.org
|
4
|
+
#
|
5
|
+
# MExiCo is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU Lesser General Public License as
|
7
|
+
# published by the Free Software Foundation, either version 3 of
|
8
|
+
# the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# MExiCo is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with MExiCo. If not, see
|
17
|
+
# <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
# The Design core module contains methods for implementations of the
|
20
|
+
# design class that are independent of the implementation.
|
21
|
+
module Mexico::Core::DesignCore
|
22
|
+
|
23
|
+
# simple test method that can be called to see whether the module
|
24
|
+
# was included successfully
|
25
|
+
def core_included?
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
|