zenlish 0.2.00 → 0.2.01

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68fb4d0914b284ffab37ba5f91c325918bcfaa4948adea0a747297e325c93fe6
4
- data.tar.gz: e83dd3b97f088defef045fb01d5d6a7be202f02d4c45e85cdce3f2f718cf9ef2
3
+ metadata.gz: 18b53b01ebe8e3f9a895026ae2b63c7753081ed12572a16d75dc35f943b479e9
4
+ data.tar.gz: 74def3a1abe88f1fa457ee151bd2420c682aedbeecf36a62a857b5e0327e43ab
5
5
  SHA512:
6
- metadata.gz: 3de436eaced4062aade3ca3dc2d94915c284c2b38a5775ba3d6880d676cc8d0e3773a244eb1086ddca93f71c265f494b548fb114e7c30ea3b52ad1dbb8694a19
7
- data.tar.gz: 7f55f80aad57993fcd1cadf75721f5f53fbd91fa8de6f620fb39fecd70892373dc69fe66fc3d13f43b272096aaf1c5afed60453ac126fb7c03fe9f0a1e435beb
6
+ metadata.gz: a7d8a33af3c91ab977a7f7ca9addd6ba0929e662c599dd0e5d3d5bbb3c3eb4ced11f765ce7e62c59e152600cccc94122e33066416faaab66c2893a207d89de6c
7
+ data.tar.gz: 9649988e311bfaccd0ed8ca12b1c648eddec01b27f4b3549c7518cb62e725ed03ecfb1c2de1459434b0a481aaa68bff1a4f978cf4ae33f7a3983e35b3614efe7
data/CHANGELOG.md CHANGED
@@ -1,4 +1,13 @@
1
1
  # CHANGELOG
2
+ ## [0.2.01] - 2020-02-02
3
+ Extending the inflection table capabilities.
4
+ Extending the inflection model to regular verbs. Zenlish can inflect all regular verbs in its dictionary.
5
+
6
+ ### Added
7
+ - Class `Inflect::FunctionCall` Now an inflection table can invoke a method of the lexeme argument.
8
+ - Class `Inflect::Membership` Now an inflection table can test whether a value is included in a set of values.
9
+ - Class `Inflect::NotEquals` Now an inflection table can test for inequality
10
+
2
11
 
3
12
  ## [0.2.00] - 2020-01-30
4
13
  A lot of internal additions, such an initial feature model, embryonic inflection model.
@@ -14,8 +23,6 @@ This is WIP.
14
23
  - Class `WordClass` ca have its own set of feature definitions.
15
24
  - Class `Noun` has the feature definitions for: `NUMBER`, `COUNTABILITY` and `PARADIGM`
16
25
 
17
-
18
-
19
26
  ## [0.1.25] - 2019-12-06
20
27
  __Zenlish__ can parse all sentences in lesson 1, 2 and 3-A .. 3-G (352 sentences in total) from
21
28
  [Learn These Words First](http://learnthesewordsfirst.com/).
data/README.md CHANGED
@@ -136,7 +136,7 @@ The milestone sub-goals are:
136
136
  - Zenlish should be able to parse all the example sentences
137
137
 
138
138
  #### B) Associate lexical features to terms in lexicon
139
- The sub-goals are:
139
+ *STARTED* The sub-goals are:
140
140
  - To enrich the lexicon entries with lexical and syntactical features.
141
141
  - Zenlish should be able to derive the declensions of nouns, conjugation of verbs,
142
142
  - Also Zenlish should detect agreement errors
@@ -0,0 +1,17 @@
1
+ require_relative 'atomic_o_expression'
2
+
3
+ module Zenlish
4
+ module Inflect
5
+ class FunctionCall < AtomicOExpression
6
+ attr_reader :mth_name
7
+
8
+ def initialize(aMethodName)
9
+ @mth_name = aMethodName
10
+ end
11
+
12
+ def generate(_headings, lexeme, _values)
13
+ lexeme.send(mth_name)
14
+ end
15
+ end # class
16
+ end # module
17
+ end # module
@@ -21,12 +21,17 @@ module Zenlish
21
21
  end
22
22
 
23
23
  def inflect(aLexeme, theConstraints)
24
+ constraints = if theConstraints.nil? || theConstraints.empty?
25
+ Array.new(headings.size) { |_i| nil }
26
+ else
27
+ theConstraints
28
+ end
24
29
  err_msg = "Table has #{headings.size} headings."
25
- raise StandardError, err_msg if theConstraints.size != headings.size
30
+ raise StandardError, err_msg if constraints.size != headings.size
26
31
  actuals = []
27
32
  headings.each_with_index do |hd, idx|
28
- if theConstraints[idx]
29
- actuals << theConstraints[idx]
33
+ if constraints[idx]
34
+ actuals << constraints[idx]
30
35
  else
31
36
  actuals << hd.evaluate_for(aLexeme)
32
37
  end
@@ -2,9 +2,12 @@ require_relative 'feature_heading'
2
2
  require_relative 'method_heading'
3
3
  require_relative 'formal_argument'
4
4
  require_relative 'equals_literal'
5
+ require_relative 'not_equals_literal'
5
6
  require_relative 'unconditionally_true'
6
7
  require_relative 'matches_pattern'
8
+ require_relative 'membership'
7
9
  require_relative 'input_asis'
10
+ require_relative 'function_call'
8
11
  require_relative 'concatenation'
9
12
  require_relative 'substitution'
10
13
  require_relative 'inflection_rule'
@@ -73,6 +76,22 @@ module Zenlish
73
76
  equality_cond
74
77
  end
75
78
 
79
+ def not_equal(aValue)
80
+ arg = FormalArgument.new(conds.size)
81
+ inequality_cond = NotEqualsLiteral.new(arg, aValue)
82
+ conds << inequality_cond
83
+
84
+ inequality_cond
85
+ end
86
+
87
+ def in?(*theMembers)
88
+ arg = FormalArgument.new(conds.size)
89
+ membership_cond = Membership.new(arg, theMembers)
90
+ conds << membership_cond
91
+
92
+ membership_cond
93
+ end
94
+
76
95
  def dont_care
77
96
  item = UnconditionallyTrue.new
78
97
  conds << item
@@ -95,6 +114,10 @@ module Zenlish
95
114
  match_cond
96
115
  end
97
116
 
117
+ def func(aFuncName)
118
+ FunctionCall.new(aFuncName)
119
+ end
120
+
98
121
  def sub(original, pattern, replacement)
99
122
  Substitution.new(original, pattern, replacement)
100
123
  end
@@ -0,0 +1,25 @@
1
+ require_relative 'unary_input_expression'
2
+
3
+ module Zenlish
4
+ module Inflect
5
+ class Membership < UnaryInputExpression
6
+ attr_reader :members
7
+
8
+ def initialize(anArgument, theMembers)
9
+ super(anArgument)
10
+ @members = theMembers
11
+ end
12
+
13
+ def success?(headings, lexeme, actuals)
14
+ if actuals.empty?
15
+ hd = headings[argument.index]
16
+ feat_def = hd.evaluate_for(lexeme)
17
+ members.all? { |memb| feat_def.domain.include?(memb) }
18
+ else
19
+ val = actuals[argument.index]
20
+ members.include?(val)
21
+ end
22
+ end
23
+ end # class
24
+ end # module
25
+ end # module
@@ -0,0 +1,25 @@
1
+ require_relative 'unary_input_expression'
2
+
3
+ module Zenlish
4
+ module Inflect
5
+ class NotEqualsLiteral < UnaryInputExpression
6
+ attr_reader :literal
7
+
8
+ def initialize(anArgument, aLiteral)
9
+ super(anArgument)
10
+ @literal = aLiteral
11
+ end
12
+
13
+ def success?(headings, lexeme, actuals)
14
+ if actuals.empty?
15
+ hd = headings[argument.index]
16
+ feat_def = hd.evaluate_for(lexeme)
17
+ !feat_def.domain.include?(literal)
18
+ else
19
+ val = actuals[argument.index]
20
+ val != literal
21
+ end
22
+ end
23
+ end # class
24
+ end # module
25
+ end # module
@@ -14,11 +14,13 @@ unless defined?(Zenlish::Lang::Dictionary)
14
14
  # @param aLemma [String] is the canonical form, dictionary form,
15
15
  # or citation form of a headword.
16
16
  # @param aWClassName [String] the name of a word class.
17
- def self.add_entry(aLemma, aWClassName, aFeatureHash = nil)
17
+ def self.add_entry(aLemma, aWClassName, aFeatureHash = nil, &aBlock)
18
18
  entry = Zenlish::Lex::LexicalEntry.new(aLemma)
19
19
  wclass = Dictionary.name2terminal[aWClassName]
20
20
  raise StandardError, "Undefined word class for '#{aLemma}'" unless wclass
21
- lexeme = Zenlish::Lex::Lexeme.new(wclass, entry, aFeatureHash).freeze
21
+ lexeme = Zenlish::Lex::Lexeme.new(wclass, entry, aFeatureHash)
22
+ lexeme.instance_exec(&aBlock) if block_given?
23
+ lexeme.freeze
22
24
  Dictionary.add_entry(entry.freeze)
23
25
  end
24
26
 
@@ -7,8 +7,8 @@ module Zenlish
7
7
  # relate to the lexeme for verb 'hide'. Also called 'dictionary word'.
8
8
  class Lexeme
9
9
  include Feature::FeatureStructDefBearer
10
-
11
- # @return [Zenlish::WClasses::WordClass]
10
+
11
+ # @return [Zenlish::WClasses::WordClass] the word class to which the lexeme belongs
12
12
  attr_reader :wclass
13
13
 
14
14
  # @param aWClass [WClasses::WordClass, Rley::Syntax::Terminal]
@@ -18,32 +18,37 @@ module Zenlish
18
18
  @wclass = aWClass
19
19
  @entry = anEntry.object_id
20
20
  anEntry.add_lexeme(self)
21
-
21
+
22
22
  p_struct = aWClass.kind_of?(WClasses::WordClass) ? aWClass.struct : nil
23
23
  overriding_struct_defs = aFeatureHash.nil? ? {} : aFeatureHash
24
24
  init_struct_def(p_struct, overriding_struct_defs)
25
25
  end
26
26
 
27
- # @return [Zenlish::Lex::LexicalEntry]
27
+ # @return [Zenlish::Lex::LexicalEntry] Link to its dictionary entry (headword)
28
28
  def entry
29
29
  ObjectSpace._id2ref(@entry)
30
30
  end
31
-
31
+
32
+ # Inflect the lexeme according the default paradigm of the word class.
33
+ # @param constraints [Array] Array of values (for each heading of inflection table
34
+ # @return [String] The word form (spelling) inflected to the given contraints.
32
35
  def inflect(constraints)
33
36
  table = paradigm
34
37
  table.inflect(self, constraints)
35
38
  end
36
39
 
37
- # @return [String]
40
+ # @return [String] the base (dictionary) form.
38
41
  def lemma
39
42
  entry.lemma
40
43
  end
41
44
 
45
+ # Return the inflection paradigm for the lexeme.
46
+ # @return [Inflect::InflectionTable]
42
47
  def paradigm
43
48
  paradigm_feat_def = self['PARADIGM']
44
- wclass.paradigms[paradigm_feat_def.default.val]
49
+ wclass.paradigms[paradigm_feat_def.default.val]
45
50
  end
46
-
51
+
47
52
  alias base_form lemma
48
53
  end # class
49
54
  end # module
@@ -1,3 +1,3 @@
1
1
  module Zenlish
2
- VERSION = '0.2.00'.freeze
2
+ VERSION = '0.2.01'.freeze
3
3
  end
@@ -26,8 +26,8 @@ module Zenlish
26
26
  feature_heading 'NUMBER'
27
27
  method_heading 'base_form'
28
28
  rule([equals(:singular), dont_care], col('base_form'))
29
- rule([equals(:plural), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ies'))
30
- rule([equals(:plural), dont_care], concat(col('base_form'), 's'))
29
+ rule([equals(:plural), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ies'))
30
+ rule([equals(:plural), dont_care], concat(col('base_form'), 's'))
31
31
  end
32
32
  add_paradigm(table)
33
33
 
@@ -2,8 +2,32 @@ require_relative 'lexical_verb'
2
2
 
3
3
  module Zenlish
4
4
  module WClasses
5
- # TODO: document
6
5
  class IrregularVerb < LexicalVerb
6
+ # @return [Array<String>] [the past simple form, past participle form].
7
+ attr_writer :forms
8
+
9
+ def initialize
10
+ super()
11
+ init_feature_defs
12
+ end
13
+
14
+ def past_simple
15
+ raise StandardError
16
+ end
17
+
18
+ def past_participle
19
+ raise StandardError
20
+ end
21
+
22
+ private
23
+
24
+ def init_feature_defs
25
+ super()
26
+ # Define standard feature definitions for irregular verbs.
27
+ feature_def_dsl {
28
+ feature_def 'PARADIGM' => [identifier, 'Irregular_form'] # 2nd item is default value
29
+ }
30
+ end
7
31
  end # class
8
32
  end # module
9
33
  end # module
@@ -2,8 +2,10 @@ require_relative 'verb'
2
2
 
3
3
  module Zenlish
4
4
  module WClasses
5
- # TODO: document
6
5
  class LexicalVerb < Verb
6
+ def initialize
7
+ super
8
+ end
7
9
  end # class
8
10
  end # module
9
11
  end # module
@@ -4,6 +4,38 @@ module Zenlish
4
4
  module WClasses
5
5
  # TODO: document 'touch'
6
6
  class RegularVerb < LexicalVerb
7
+ def initialize
8
+ super
9
+ @paradigms = {}
10
+ init_paradigms
11
+ end
12
+
13
+ private
14
+
15
+ def init_paradigms
16
+ builder = Inflect::InflectionTableBuilder.new
17
+ table = builder.build('Regular_inflection') do
18
+ feature_heading 'PERSON'
19
+ feature_heading 'NUMBER'
20
+ feature_heading 'TIME'
21
+ method_heading 'base_form'
22
+ # PERSON NUMBER TIME base_form
23
+ rule([not_equal(:third), dont_care, equals(:present), dont_care], col('base_form'))
24
+ rule([equals(:third), equals(:singular), equals(:present), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ies'))
25
+ rule([equals(:third), equals(:singular), equals(:present), matches(/(?:[osxz]|ch|sh)$/)], concat(col('base_form'), 'es'))
26
+ rule([equals(:third), equals(:singular), equals(:present), dont_care], concat(col('base_form'), 's'))
27
+ rule([dont_care, dont_care, equals(:progressive), matches(/e$/)], sub(col('base_form'), /e$/, 'ing'))
28
+ rule([dont_care, dont_care, equals(:progressive), dont_care], concat(col('base_form'), 'ing'))
29
+ rule([dont_care, dont_care, in?(:past_simple, :past_participle), matches(/e$/)], concat(col('base_form'), 'd'))
30
+ rule([dont_care, dont_care, in?(:past_simple, :past_participle), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ied'))
31
+ rule([dont_care, dont_care, in?(:past_simple, :past_participle), dont_care], concat(col('base_form'), 'ed'))
32
+ end
33
+ add_paradigm(table)
34
+ end
35
+
36
+ def add_paradigm(anInflectionTable)
37
+ @paradigms[anInflectionTable.name] = anInflectionTable
38
+ end
7
39
  end # class
8
40
  end # module
9
41
  end # module
@@ -1,4 +1,5 @@
1
1
  require_relative 'word_class'
2
+ require_relative '../inflect/inflection_table_builder'
2
3
 
3
4
  module Zenlish
4
5
  module WClasses
@@ -6,12 +7,28 @@ module Zenlish
6
7
  # notionally as a 'doing' word (i.e. a word that describes the action
7
8
  # in a clause).
8
9
  class Verb < WordClass
10
+ def initialize
11
+ super()
12
+ init_feature_defs
13
+ end
9
14
 
10
15
  # As all verbs inflect, or change form, to reflect changes in tense,
11
16
  # person, number, and voice, they are, by definition, variable.
12
17
  def invariable?
13
18
  false
14
19
  end
20
+
21
+ private
22
+
23
+ def init_feature_defs
24
+ # Create standard feature definitions for lexical verbs.
25
+ feature_def_dsl {
26
+ feature_def 'NUMBER' => enumeration(:singular, :plural)
27
+ feature_def 'PERSON' => enumeration(:first, :second, :third)
28
+ feature_def 'TIME' => enumeration(:present, :progressive, :past_simple, :past_participle)
29
+ feature_def 'PARADIGM' => [identifier, 'Regular_inflection'] # 2nd item is default value
30
+ }
31
+ end
15
32
  end # class
16
33
  end # module
17
34
  end # module
@@ -16,7 +16,7 @@ module Zenlish
16
16
  subject { EqualsLiteral.new(an_argument, feat_val) }
17
17
 
18
18
  context 'Initialization:' do
19
- it 'should be initialized with a method name' do
19
+ it 'should be initialized with a formal argument and a literal' do
20
20
  expect { EqualsLiteral.new(an_argument, feat_val) }.not_to raise_error
21
21
  end
22
22
 
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ostruct'
4
+ # Load the class under test
5
+ require_relative '../../../lib/zenlish/inflect/function_call'
6
+
7
+ module Zenlish
8
+ module Inflect
9
+ describe FunctionCall do
10
+ subject { FunctionCall.new('greet') }
11
+
12
+ context 'Initialization:' do
13
+ it 'should be initialized with a text literal' do
14
+ expect { FunctionCall.new('greet') }.not_to raise_error
15
+ end
16
+
17
+ it 'should know its method name' do
18
+ expect(subject.mth_name).to eq('greet')
19
+ end
20
+ end # context
21
+
22
+ context 'Provided services:' do
23
+ it 'should return the affix during word form generation' do
24
+ headings = double('fake-headings')
25
+ lexeme = OpenStruct.new(:greet => 'Hello, world')
26
+ values = double('fake-values')
27
+ expect(subject.generate(headings, lexeme, values)).to eq('Hello, world')
28
+ end
29
+ end # context
30
+ end # describe
31
+ end # module
32
+ end # module
@@ -97,7 +97,7 @@ module Zenlish
97
97
 
98
98
  MockFeatureBearer = Struct.new(:NUMBER, :base_form)
99
99
 
100
- it 'should build tables conform to specs' do
100
+ it 'should build default paradigm for common nouns' do
101
101
  table = subject.build('Common_form') do
102
102
  feature_heading 'NUMBER'
103
103
  method_heading 'base_form'
@@ -121,6 +121,86 @@ module Zenlish
121
121
  mck_3['NUMBER'] = :plural
122
122
  expect(table.inflect(mck_3, [nil, nil])).to eq('bodies')
123
123
  end
124
+
125
+ MockRegularVerb = Struct.new(:base_form, :PERSON, :NUMBER, :TIME)
126
+ it 'should build default paradigm for regular verbs' do
127
+ table = subject.build('Regular_form') do
128
+ feature_heading 'PERSON'
129
+ feature_heading 'NUMBER'
130
+ feature_heading 'TIME'
131
+ method_heading 'base_form'
132
+ # PERSON NUMBER TIME base_form
133
+ rule([not_equal(:third), dont_care, equals(:present), dont_care], col('base_form'))
134
+ rule([equals(:third), equals(:singular), equals(:present), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ies'))
135
+ rule([equals(:third), equals(:singular), equals(:present), matches(/(?:[osxz]|ch|sh)$/)], concat(col('base_form'), 'es'))
136
+ rule([equals(:third), equals(:singular), equals(:present), dont_care], concat(col('base_form'), 's'))
137
+ rule([dont_care, dont_care, equals(:progressive), matches(/e$/)], sub(col('base_form'), /e$/, 'ing'))
138
+ rule([dont_care, dont_care, equals(:progressive), dont_care], concat(col('base_form'), 'ing'))
139
+ rule([dont_care, dont_care, in?(:past_simple, :past_participle), matches(/e$/)], concat(col('base_form'), 'd'))
140
+ rule([dont_care, dont_care, in?(:past_simple, :past_participle), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ied'))
141
+ rule([dont_care, dont_care, in?(:past_simple, :past_participle), dont_care], concat(col('base_form'), 'ed'))
142
+ end
143
+
144
+ verb_1 = MockRegularVerb.new('belong', :first, :singular, :present)
145
+ expect(table.inflect(verb_1, [nil, nil, nil, nil] )).to eq('belong')
146
+ expect(table.inflect(verb_1, [:third, nil, nil, nil] )).to eq('belongs')
147
+ expect(table.inflect(verb_1, [nil, :plural, nil, nil] )).to eq('belong')
148
+ expect(table.inflect(verb_1, [nil, nil, :progressive, nil] )).to eq('belonging')
149
+ expect(table.inflect(verb_1, [nil, nil, :past_simple, nil] )).to eq('belonged')
150
+ expect(table.inflect(verb_1, [nil, nil, :past_participle, nil])).to eq('belonged')
151
+
152
+ verb_2 = MockRegularVerb.new('try', :first, :singular, :present)
153
+ expect(table.inflect(verb_2, [nil, nil, nil, nil] )).to eq('try')
154
+ expect(table.inflect(verb_2, [:third, nil, nil, nil] )).to eq('tries')
155
+ expect(table.inflect(verb_2, [nil, :plural, nil, nil] )).to eq('try')
156
+ expect(table.inflect(verb_2, [nil, nil, :progressive, nil] )).to eq('trying')
157
+ expect(table.inflect(verb_2, [nil, nil, :past_simple, nil] )).to eq('tried')
158
+ expect(table.inflect(verb_2, [nil, nil, :past_participle, nil])).to eq('tried')
159
+
160
+ verb_3 = MockRegularVerb.new('touch', :first, :singular, :present)
161
+ expect(table.inflect(verb_3, [:second,nil, nil, nil] )).to eq('touch')
162
+ expect(table.inflect(verb_3, [:third, nil, nil, nil] )).to eq('touches')
163
+ expect(table.inflect(verb_3, [nil, :plural, nil, nil] )).to eq('touch')
164
+ expect(table.inflect(verb_3, [nil, nil, :progressive, nil] )).to eq('touching')
165
+ expect(table.inflect(verb_3, [nil, nil, :past_simple, nil] )).to eq('touched')
166
+ expect(table.inflect(verb_3, [nil, nil, :past_participle, nil])).to eq('touched')
167
+
168
+ verb_4 = MockRegularVerb.new('cause', :first, :singular, :present)
169
+ expect(table.inflect(verb_4, [nil, nil, nil, nil] )).to eq('cause')
170
+ expect(table.inflect(verb_4, [:third, nil, nil, nil] )).to eq('causes')
171
+ expect(table.inflect(verb_4, [nil, :plural, nil, nil] )).to eq('cause')
172
+ expect(table.inflect(verb_4, [nil, nil, :progressive, nil] )).to eq('causing')
173
+ expect(table.inflect(verb_4, [nil, nil, :past_simple, nil] )).to eq('caused')
174
+ expect(table.inflect(verb_4, [nil, nil, :past_participle, nil])).to eq('caused')
175
+ end
176
+
177
+ # MockIrregularVerb = Struct.new(:base_form, :PERSON, :NUMBER, :TIME)
178
+ # it 'should build default paradigm for irregular verbs' do
179
+ # table = subject.build('Irregular_form') do
180
+ # feature_heading 'PERSON'
181
+ # feature_heading 'NUMBER'
182
+ # feature_heading 'TIME'
183
+ # method_heading 'base_form'
184
+ # # PERSON NUMBER TIME base_form
185
+ # rule([not_equal(:third), dont_care, equals(:present), dont_care], col('base_form'))
186
+ # rule([equals(:third), equals(:singular), equals(:present), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ies'))
187
+ # rule([equals(:third), equals(:singular), equals(:present), matches(/(?:[osxz]|ch|sh)$/)], concat(col('base_form'), 'es'))
188
+ # rule([equals(:third), equals(:singular), equals(:present), dont_care], concat(col('base_form'), 's'))
189
+ # rule([dont_care, dont_care, equals(:progressive), matches(/e$/)], sub(col('base_form'), /e$/, 'ing'))
190
+ # rule([dont_care, dont_care, equals(:progressive), dont_care], concat(col('base_form'), 'ing'))
191
+ # rule([dont_care, dont_care, in?(:past_simple, :past_participle), matches(/e$/)], concat(col('base_form'), 'd'))
192
+ # rule([dont_care, dont_care, in?(:past_simple, :past_participle), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ied'))
193
+ # rule([dont_care, dont_care, in?(:past_simple, :past_participle), dont_care], concat(col('base_form'), 'ed'))
194
+ # end
195
+
196
+ # verb_1 = MockIrregularVerb.new('choose', :first, :singular, :present)
197
+ # expect(table.inflect(verb_1, [nil, nil, nil, nil] )).to eq('choose')
198
+ # expect(table.inflect(verb_1, [:third, nil, nil, nil] )).to eq('chooses')
199
+ # expect(table.inflect(verb_1, [nil, :plural, nil, nil] )).to eq('choose')
200
+ # expect(table.inflect(verb_1, [nil, nil, :progressive, nil] )).to eq('choosing')
201
+ # expect(table.inflect(verb_1, [nil, nil, :past_simple, nil] )).to eq('chose')
202
+ # expect(table.inflect(verb_1, [nil, nil, :past_participle, nil])).to eq('chosen')
203
+ # end
124
204
  end # context
125
205
  end # describe
126
206
  end # module
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../lib/zenlish/wclasses/common_noun'
4
+ require_relative '../../../lib/zenlish/lex/lexeme'
5
+ require_relative '../../../lib/zenlish/lex/lexical_entry'
6
+ require_relative '../../../lib/zenlish/inflect/feature_heading'
7
+ require_relative '../../../lib/zenlish/inflect/formal_argument'
8
+ # Load the class under test
9
+ require_relative '../../../lib/zenlish/inflect/membership'
10
+
11
+ module Zenlish
12
+ module Inflect
13
+ describe Membership do
14
+ let(:an_argument) { FormalArgument.new(1) }
15
+ let(:feat_val) { [:singular, :plural] }
16
+ subject { Membership.new(an_argument, feat_val) }
17
+
18
+ context 'Initialization:' do
19
+ it 'should be initialized with a formal argument and an array' do
20
+ expect { Membership.new(an_argument, feat_val) }.not_to raise_error
21
+ end
22
+
23
+ it 'should know its argument' do
24
+ expect(subject.argument).to eq(an_argument)
25
+ end
26
+
27
+ it 'should know the array of literals' do
28
+ expect(subject.members).to eq(feat_val)
29
+ end
30
+ end # context
31
+
32
+ context 'Provided services:' do
33
+ it 'should test the actual values' do
34
+ lexeme = double('dummy-lexeme')
35
+ headings = double('fake-headings')
36
+ actual_args = [nil, :plural, nil]
37
+ expect(subject.success?(headings, lexeme, actual_args)).to be_truthy
38
+ actual_args[1] = :singular
39
+ expect(subject.success?(headings, lexeme, actual_args)).to be_truthy
40
+ actual_args[1] = :dual
41
+ expect(subject.success?(headings, lexeme, actual_args)).to be_falsy
42
+ end
43
+
44
+ # it 'should test the lexeme' do
45
+ # c_noun = WClasses::CommonNoun.new
46
+ # entry = Lex::LexicalEntry.new('animal')
47
+ # lexeme = Lex::Lexeme.new(c_noun, entry)
48
+ # headings = [nil, FeatureHeading.new('NUMBER'), nil]
49
+ # expect(subject.success?(headings, lexeme, [])).to be_truthy
50
+
51
+ # instance = Membership.new(an_argument, :singular)
52
+ # expect(instance.success?(headings, lexeme, [])).to be_truthy
53
+
54
+ # instance = Membership.new(an_argument, :irregular)
55
+ # expect(instance.success?(headings, lexeme, [])).to be_falsey
56
+ # end
57
+ end # context
58
+ end # describe
59
+ end # module
60
+ end # module
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../lib/zenlish/wclasses/common_noun'
4
+ require_relative '../../../lib/zenlish/lex/lexeme'
5
+ require_relative '../../../lib/zenlish/lex/lexical_entry'
6
+ require_relative '../../../lib/zenlish/inflect/feature_heading'
7
+ require_relative '../../../lib/zenlish/inflect/formal_argument'
8
+ # Load the class under test
9
+ require_relative '../../../lib/zenlish/inflect/not_equals_literal'
10
+
11
+ module Zenlish
12
+ module Inflect
13
+ describe NotEqualsLiteral do
14
+ let(:an_argument) { FormalArgument.new(1) }
15
+ let(:feat_val) { :plural }
16
+ subject { NotEqualsLiteral.new(an_argument, feat_val) }
17
+
18
+ context 'Initialization:' do
19
+ it 'should be initialized with formal argument and a literal' do
20
+ expect { NotEqualsLiteral.new(an_argument, feat_val) }.not_to raise_error
21
+ end
22
+
23
+ it 'should know its argument' do
24
+ expect(subject.argument).to eq(an_argument)
25
+ end
26
+
27
+ it 'should know the literal' do
28
+ expect(subject.literal).to eq(feat_val)
29
+ end
30
+ end # context
31
+
32
+ context 'Provided services:' do
33
+ it 'should test the actual argument' do
34
+ lexeme = double('dummy-lexeme')
35
+ headings = double('fake-headings')
36
+ actual_args = [nil, :plural, nil]
37
+ expect(subject.success?(headings, lexeme, actual_args)).to be_falsy
38
+ actual_args[1] = :singular
39
+ expect(subject.success?(headings, lexeme, actual_args)).to be_truthy
40
+ end
41
+
42
+ it 'should test the lexeme' do
43
+ c_noun = WClasses::CommonNoun.new
44
+ entry = Lex::LexicalEntry.new('animal')
45
+ lexeme = Lex::Lexeme.new(c_noun, entry)
46
+ headings = [nil, FeatureHeading.new('NUMBER'), nil]
47
+ expect(subject.success?(headings, lexeme, [])).to be_falsy
48
+
49
+ instance = NotEqualsLiteral.new(an_argument, :singular)
50
+ expect(instance.success?(headings, lexeme, [])).to be_falsy
51
+
52
+ instance = NotEqualsLiteral.new(an_argument, :irregular)
53
+ expect(instance.success?(headings, lexeme, [])).to be_truthy
54
+ end
55
+ end # context
56
+ end # describe
57
+ end # module
58
+ end # module
@@ -47,6 +47,10 @@ module Zenlish
47
47
  instance = Lexeme.new(a_wclass, an_entry, a_feat_struct_def)
48
48
  expect(instance['NUMBER'].default.val).to eq(:plural)
49
49
  end
50
+
51
+ it 'should know its inflection paradigm' do
52
+ expect(subject.paradigm).to be_kind_of(Inflect::InflectionTable)
53
+ end
50
54
  end # context
51
55
  end # describe
52
56
  end # module
@@ -14,8 +14,9 @@ module Zenlish
14
14
  end
15
15
  end # context
16
16
 
17
- # context 'Provided services:' do
18
- # end # context
17
+ context 'Provided services:' do
18
+
19
+ end # context
19
20
  end # describe
20
21
  end # module
21
22
  end # module
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../spec_helper' # Use the RSpec framework
4
+
5
+ # Load the class under test
6
+ require_relative '../../../lib/zenlish/wclasses/lexical_verb'
7
+
8
+ module Zenlish
9
+ module WClasses
10
+ describe LexicalVerb do
11
+ subject { LexicalVerb.new }
12
+
13
+ context 'Initialization:' do
14
+ it 'should be initialized without argument' do
15
+ expect { LexicalVerb.new }.not_to raise_error
16
+ end
17
+ end # context
18
+
19
+ context 'Provided services:' do
20
+ it 'should know its inherited feature definitions' do
21
+ expect(subject['NUMBER']).to be_kind_of(Feature::FeatureDef)
22
+ expect(subject['PERSON']).to be_kind_of(Feature::FeatureDef)
23
+ expect(subject['PARADIGM'].default.val).to eq('Regular_inflection')
24
+ end
25
+ end # context
26
+ end # describe
27
+ end # module
28
+ end # module
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../spec_helper' # Use the RSpec framework
4
+ require_relative '../../../lib/zenlish/lex/lexical_entry'
5
+ require_relative '../../../lib/zenlish/lex/lexeme'
6
+
7
+ # Load the class under test
8
+ require_relative '../../../lib/zenlish/wclasses/regular_verb'
9
+
10
+ module Zenlish
11
+ module WClasses
12
+ describe RegularVerb do
13
+ subject { RegularVerb.new }
14
+
15
+ context 'Initialization:' do
16
+ it 'should be initialized without argument' do
17
+ expect { RegularVerb.new }.not_to raise_error
18
+ end
19
+ end # context
20
+
21
+ context 'Provided services:' do
22
+ it 'should know its inherited feature definitions' do
23
+ expect(subject['NUMBER']).to be_kind_of(Feature::FeatureDef)
24
+ expect(subject['PERSON']).to be_kind_of(Feature::FeatureDef)
25
+ expect(subject['PARADIGM'].default.val).to eq('Regular_inflection')
26
+ end
27
+
28
+ let(:present_1sg) { [:first, :singular, :present, nil] }
29
+ let(:present_3sg) { [:third, :singular, :present, nil] }
30
+ let(:present_1pl) { [:first, :plural, :present, nil] }
31
+ let(:progressive) { [nil, nil, :progressive, nil] }
32
+ let(:past_simple) { [nil, nil, :past_simple, nil] }
33
+ let(:past_participle) { [nil, nil, :past_participle, nil] }
34
+
35
+ def build_verb(aBaseForm)
36
+ entry = Zenlish::Lex::LexicalEntry.new(aBaseForm)
37
+ lexeme = Zenlish::Lex::Lexeme.new(subject, entry)
38
+ end
39
+
40
+ def test_inflection_of(verb_form, pairs)
41
+ verb = build_verb(verb_form)
42
+ pairs.each do |(constraints, expected_form)|
43
+ expect(verb.inflect(constraints)).to eq(expected_form)
44
+ end
45
+ end
46
+
47
+ it 'should how to inflect regular verbs' do
48
+ expectations_1 = [
49
+ [present_1sg, 'exist'],
50
+ [present_3sg, 'exists'],
51
+ [present_1pl, 'exist'],
52
+ [progressive, 'existing'],
53
+ [past_simple, 'existed'],
54
+ [past_participle, 'existed']
55
+ ]
56
+ test_inflection_of('exist', expectations_1)
57
+
58
+ expectations_2 = [
59
+ [present_1sg, 'move'],
60
+ [present_3sg, 'moves'],
61
+ [present_1pl, 'move'],
62
+ [progressive, 'moving'],
63
+ [past_simple, 'moved'],
64
+ [past_participle, 'moved']
65
+ ]
66
+ test_inflection_of('move', expectations_2)
67
+
68
+ expectations_3 = [
69
+ [present_1sg, 'try'],
70
+ [present_3sg, 'tries'],
71
+ [present_1pl, 'try'],
72
+ [progressive, 'trying'],
73
+ [past_simple, 'tried'],
74
+ [past_participle, 'tried']
75
+ ]
76
+ test_inflection_of('try', expectations_3)
77
+
78
+ expectations_4 = [
79
+ [present_1sg, 'touch'],
80
+ [present_3sg, 'touches'],
81
+ [present_1pl, 'touch'],
82
+ [progressive, 'touching'],
83
+ [past_simple, 'touched'],
84
+ [past_participle, 'touched']
85
+ ]
86
+ test_inflection_of('touch', expectations_4)
87
+ end
88
+ end # context
89
+ end # describe
90
+ end # module
91
+ end # module
@@ -15,9 +15,15 @@ module Zenlish
15
15
  end # context
16
16
 
17
17
  context 'Provided services:' do
18
- it 'should know that it it is variable (has inflected forms)' do
18
+ it 'should know that it has inflected forms' do
19
19
  expect(subject).not_to be_invariable
20
20
  end
21
+
22
+ it 'should know its feature definitions' do
23
+ expect(subject['NUMBER']).to be_kind_of(Feature::FeatureDef)
24
+ expect(subject['PERSON']).to be_kind_of(Feature::FeatureDef)
25
+ expect(subject['PARADIGM'].default.val).to eq('Regular_inflection')
26
+ end
21
27
  end # context
22
28
  end # describe
23
29
  end # module
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zenlish
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.00
4
+ version: 0.2.01
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-30 00:00:00.000000000 Z
11
+ date: 2020-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rley
@@ -104,6 +104,7 @@ files:
104
104
  - lib/zenlish/inflect/equals_literal.rb
105
105
  - lib/zenlish/inflect/feature_heading.rb
106
106
  - lib/zenlish/inflect/formal_argument.rb
107
+ - lib/zenlish/inflect/function_call.rb
107
108
  - lib/zenlish/inflect/heading.rb
108
109
  - lib/zenlish/inflect/inflection_rule.rb
109
110
  - lib/zenlish/inflect/inflection_table.rb
@@ -112,7 +113,9 @@ files:
112
113
  - lib/zenlish/inflect/input_expression.rb
113
114
  - lib/zenlish/inflect/literal_asis.rb
114
115
  - lib/zenlish/inflect/matches_pattern.rb
116
+ - lib/zenlish/inflect/membership.rb
115
117
  - lib/zenlish/inflect/method_heading.rb
118
+ - lib/zenlish/inflect/not_equals_literal.rb
116
119
  - lib/zenlish/inflect/nullary_input_expression.rb
117
120
  - lib/zenlish/inflect/output_expression.rb
118
121
  - lib/zenlish/inflect/substitution.rb
@@ -195,13 +198,16 @@ files:
195
198
  - spec/zenlish/inflect/equals_literal_spec.rb
196
199
  - spec/zenlish/inflect/feature_heading_spec.rb
197
200
  - spec/zenlish/inflect/formal_argument_spec.rb
201
+ - spec/zenlish/inflect/function_call_spec.rb
198
202
  - spec/zenlish/inflect/inflection_rule_spec.rb
199
203
  - spec/zenlish/inflect/inflection_table_builder_spec.rb
200
204
  - spec/zenlish/inflect/inflection_table_spec.rb
201
205
  - spec/zenlish/inflect/input_asis_spec.rb
202
206
  - spec/zenlish/inflect/literal_asis_spec.rb
203
207
  - spec/zenlish/inflect/matches_pattern_spec.rb
208
+ - spec/zenlish/inflect/membership_spec.rb
204
209
  - spec/zenlish/inflect/method_heading_spec.rb
210
+ - spec/zenlish/inflect/not_equals_literal_spec.rb
205
211
  - spec/zenlish/inflect/substitution_spec.rb
206
212
  - spec/zenlish/inflect/unconditionally_true_spec.rb
207
213
  - spec/zenlish/lang/dictionary_spec.rb
@@ -219,9 +225,11 @@ files:
219
225
  - spec/zenlish/support/var2word.rb
220
226
  - spec/zenlish/wclasses/common_noun_spec.rb
221
227
  - spec/zenlish/wclasses/irregular_verb_spec.rb
228
+ - spec/zenlish/wclasses/lexical_verb_spec.rb
222
229
  - spec/zenlish/wclasses/noun_spec.rb
223
230
  - spec/zenlish/wclasses/preposition_spec.rb
224
231
  - spec/zenlish/wclasses/proper_noun_spec.rb
232
+ - spec/zenlish/wclasses/regular_verb_spec.rb
225
233
  - spec/zenlish/wclasses/verb_spec.rb
226
234
  - spec/zenlish_spec.rb
227
235
  - zenlish.gemspec
@@ -264,13 +272,16 @@ test_files:
264
272
  - spec/zenlish/inflect/equals_literal_spec.rb
265
273
  - spec/zenlish/inflect/feature_heading_spec.rb
266
274
  - spec/zenlish/inflect/formal_argument_spec.rb
275
+ - spec/zenlish/inflect/function_call_spec.rb
267
276
  - spec/zenlish/inflect/inflection_rule_spec.rb
268
277
  - spec/zenlish/inflect/inflection_table_builder_spec.rb
269
278
  - spec/zenlish/inflect/inflection_table_spec.rb
270
279
  - spec/zenlish/inflect/input_asis_spec.rb
271
280
  - spec/zenlish/inflect/literal_asis_spec.rb
272
281
  - spec/zenlish/inflect/matches_pattern_spec.rb
282
+ - spec/zenlish/inflect/membership_spec.rb
273
283
  - spec/zenlish/inflect/method_heading_spec.rb
284
+ - spec/zenlish/inflect/not_equals_literal_spec.rb
274
285
  - spec/zenlish/inflect/substitution_spec.rb
275
286
  - spec/zenlish/inflect/unconditionally_true_spec.rb
276
287
  - spec/zenlish/lang/dictionary_spec.rb
@@ -286,8 +297,10 @@ test_files:
286
297
  - spec/zenlish/parser/zparser_spec.rb
287
298
  - spec/zenlish/wclasses/common_noun_spec.rb
288
299
  - spec/zenlish/wclasses/irregular_verb_spec.rb
300
+ - spec/zenlish/wclasses/lexical_verb_spec.rb
289
301
  - spec/zenlish/wclasses/noun_spec.rb
290
302
  - spec/zenlish/wclasses/preposition_spec.rb
291
303
  - spec/zenlish/wclasses/proper_noun_spec.rb
304
+ - spec/zenlish/wclasses/regular_verb_spec.rb
292
305
  - spec/zenlish/wclasses/verb_spec.rb
293
306
  - spec/zenlish_spec.rb