lex-cognitive-grammar 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7d1a6033a3d40b2be785361c3c86637af7d504cdfa3389e4501e6634a69f7bf2
4
+ data.tar.gz: d95e46dd8e3846f5dce29a3d7d1c17290a06f8df16ebb747fac388e6ae393999
5
+ SHA512:
6
+ metadata.gz: ee8709710023d006ce784491caff43246edf7e69105ae7a88935d5bbb528eb74d62e0990c6f590ee422ba3c885f8b437eed35f44014a644c6a36bd0b4fc38c91
7
+ data.tar.gz: 4eeba781ebdf5d0065e9f18bc4874c1f78c8d8b5a132f8f75675f3e5a223d4fb790a4215b3460db4614d0af66f545047ad4708dbabb8c80374306c20a91417f2
@@ -0,0 +1,16 @@
1
+ name: CI
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+
7
+ jobs:
8
+ ci:
9
+ uses: LegionIO/.github/.github/workflows/ci.yml@main
10
+
11
+ release:
12
+ needs: ci
13
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
14
+ uses: LegionIO/.github/.github/workflows/release.yml@main
15
+ secrets:
16
+ rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .rspec_status
2
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require spec_helper
2
+ --format documentation
data/.rubocop.yml ADDED
@@ -0,0 +1,52 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.4
3
+ NewCops: enable
4
+ SuggestExtensions: false
5
+
6
+ Layout/LineLength:
7
+ Max: 160
8
+
9
+ Layout/SpaceAroundEqualsInParameterDefault:
10
+ EnforcedStyle: space
11
+
12
+ Layout/HashAlignment:
13
+ EnforcedHashRocketStyle: table
14
+ EnforcedColonStyle: table
15
+
16
+ Metrics/MethodLength:
17
+ Max: 25
18
+
19
+ Metrics/ClassLength:
20
+ Max: 150
21
+
22
+ Metrics/ModuleLength:
23
+ Max: 150
24
+
25
+ Metrics/BlockLength:
26
+ Max: 40
27
+ Exclude:
28
+ - 'spec/**/*'
29
+
30
+ Metrics/AbcSize:
31
+ Max: 25
32
+
33
+ Metrics/ParameterLists:
34
+ Max: 8
35
+ MaxOptionalParameters: 8
36
+
37
+ Style/Documentation:
38
+ Enabled: false
39
+
40
+ Style/FrozenStringLiteralComment:
41
+ Enabled: true
42
+ EnforcedStyle: always
43
+
44
+ Style/OneClassPerFile:
45
+ Exclude:
46
+ - 'spec/spec_helper.rb'
47
+
48
+ Naming/FileName:
49
+ Enabled: false
50
+
51
+ Naming/PredicateMethod:
52
+ Enabled: false
data/CLAUDE.md ADDED
@@ -0,0 +1,116 @@
1
+ # lex-cognitive-grammar
2
+
3
+ **Level 3 Leaf Documentation**
4
+ - **Parent**: `/Users/miverso2/rubymine/legion/extensions-agentic/CLAUDE.md`
5
+ - **Gem**: `lex-cognitive-grammar`
6
+
7
+ ## Purpose
8
+
9
+ Models cognitive grammar — the structured mental constructions through which meaning is assembled. Based on Cognitive Linguistics: constructions are symbolic units (form-meaning pairings) stored in a construction grammar network. Construals represent specific applications of constructions to scenes. Each use of a construction strengthens its activation via Exponential Moving Average. Constructions that exceed the entrenchment threshold (0.8) become automatic. A periodic maintenance actor decays unused constructions over time.
10
+
11
+ ## Gem Info
12
+
13
+ | Field | Value |
14
+ |---|---|
15
+ | Gem name | `lex-cognitive-grammar` |
16
+ | Version | `0.1.0` |
17
+ | Namespace | `Legion::Extensions::CognitiveGrammar` |
18
+ | Ruby | `>= 3.4` |
19
+ | License | MIT |
20
+ | GitHub | https://github.com/LegionIO/lex-cognitive-grammar |
21
+
22
+ ## File Structure
23
+
24
+ ```
25
+ lib/legion/extensions/cognitive_grammar/
26
+ cognitive_grammar.rb # Top-level require
27
+ version.rb # VERSION = '0.1.0'
28
+ client.rb # Client class
29
+ helpers/
30
+ constants.rb # Construal operations, prominence types, activation labels, thresholds
31
+ construction.rb # Construction value object (form-meaning unit)
32
+ construal.rb # Construal value object (specific scene interpretation)
33
+ grammar_engine.rb # Engine: constructions, construals, activation, decay
34
+ runners/
35
+ cognitive_grammar.rb # Runner module
36
+ ```
37
+
38
+ ## Key Constants
39
+
40
+ | Constant | Value | Meaning |
41
+ |---|---|---|
42
+ | `CONSTRUAL_OPERATIONS` | array | Mental operations: `profiling`, `trajector_landmark`, `figure_ground`, `scope`, `perspective`, `dynamism` |
43
+ | `PROMINENCE_TYPES` | array | `[:trajector, :landmark, :profiled, :active_zone, :reference_point, :base]` |
44
+ | `EXPRESSION_TYPES` | array | `[:nominal, :verbal, :clausal, :prepositional, :adjectival, :constructional]` |
45
+ | `MAX_CONSTRUCTIONS` | 200 | Construction store cap |
46
+ | `MAX_CONSTRUALS` | 500 | Construal history cap |
47
+ | `DEFAULT_ACTIVATION` | 0.3 | Starting activation for new constructions |
48
+ | `ENTRENCHMENT_THRESHOLD` | 0.8 | Activation above this = entrenched (automatic) |
49
+ | `ACTIVATION_LABELS` | hash | `entrenched` (0.8+) through `dormant` |
50
+
51
+ ## Helpers
52
+
53
+ ### `Construction`
54
+
55
+ A symbolic form-meaning unit in the grammar network.
56
+
57
+ - `initialize(name:, form:, meaning:, domain:, activation: DEFAULT_ACTIVATION, construction_id: nil)`
58
+ - `use!(alpha: 0.2)` — updates activation via EMA; increments use count
59
+ - `decay!(rate: 0.01)` — decreases activation
60
+ - `entrenched?` — activation >= `ENTRENCHMENT_THRESHOLD`
61
+ - `inactive?` — activation below threshold
62
+ - `to_h`
63
+
64
+ ### `Construal`
65
+
66
+ A specific application of a construction to a scene.
67
+
68
+ - `initialize(construction_id:, scene:, operation:, prominence:, construal_id: nil)`
69
+ - `to_h`
70
+
71
+ ### `GrammarEngine`
72
+
73
+ - `create_construction(name:, form:, meaning:, domain:)` — returns `{ created:, construction_id:, construction: }` or capacity error
74
+ - `create_construal(construction_id:, scene:, operation:, prominence:)` — validates construction exists; appends to construal ring buffer
75
+ - `use_construction(construction_id:)` — fires EMA update; returns before/after activation + entrenchment state
76
+ - `entrenched_constructions(limit: 20)` — sorted by activation descending
77
+ - `decay_all(rate: 0.01)` — decays all constructions
78
+ - `prune_inactive(threshold: 0.05)` — removes constructions below activation floor
79
+ - `constructions_by_domain` — groups by domain
80
+ - `most_used(limit: 10)` — sorted by use_count
81
+ - `grammar_report` — full stats
82
+
83
+ ## Runners
84
+
85
+ **Module**: `Legion::Extensions::CognitiveGrammar::Runners::CognitiveGrammar`
86
+
87
+ | Method | Key Args | Returns |
88
+ |---|---|---|
89
+ | `create_grammar_construction` | `name:`, `form:`, `meaning:`, `domain:` | `{ success:, construction_id:, construction: }` |
90
+ | `create_grammar_construal` | `construction_id:`, `scene:`, `operation:`, `prominence:` | `{ success:, construal_id:, construal: }` |
91
+ | `use_grammar_construction` | `construction_id:` | `{ success:, before:, after:, entrenched: }` |
92
+ | `construals_for_scene_report` | `scene:` | `{ success:, construals: }` |
93
+ | `entrenched_constructions_report` | `limit: 20` | `{ success:, constructions: }` |
94
+ | `constructions_by_domain_report` | — | `{ success:, domains: }` |
95
+ | `most_used_constructions` | `limit: 10` | `{ success:, constructions: }` |
96
+ | `update_cognitive_grammar` | — | `{ success:, decayed: }` — runs decay pass |
97
+ | `cognitive_grammar_stats` | — | engine `to_h` |
98
+
99
+ Private: `grammar_engine` — memoized `GrammarEngine`. Logs via `log_debug` helper.
100
+
101
+ ## Integration Points
102
+
103
+ - **`lex-tick`**: `update_cognitive_grammar` is the maintenance operation; can be wired into `memory_consolidation` or a dedicated grammar-maintenance phase.
104
+ - **`lex-memory`**: Construction activation mirrors memory trace strength. Entrenched constructions could be co-stored as procedural memory traces in lex-memory for cross-extension retrieval.
105
+ - **`lex-cognitive-flexibility`**: Switching task sets may require activating constructions appropriate to the new domain. Grammar constructions and task-set rules operate at complementary abstraction levels.
106
+
107
+ ## Development Notes
108
+
109
+ - `use_construction` updates activation via EMA on each call. Frequent use rapidly entrenches a construction; infrequent use combined with periodic `decay_all` calls keeps the grammar network trimmed.
110
+ - `prune_inactive` is destructive — constructions removed cannot be recovered. Call with a conservative threshold.
111
+ - `construals_for_scene_report` searches the construal buffer for exact scene string matches.
112
+ - In-memory only.
113
+
114
+ ---
115
+
116
+ **Maintained By**: Matthew Iverson (@Esity)
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rspec', '~> 3.13'
8
+ gem 'rubocop', '~> 1.75', require: false
9
+ gem 'rubocop-rspec', require: false
10
+ end
11
+
12
+ gem 'legion-gaia', path: '../../legion-gaia'
data/Gemfile.lock ADDED
@@ -0,0 +1,78 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lex-cognitive-grammar (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ addressable (2.8.9)
10
+ public_suffix (>= 2.0.2, < 8.0)
11
+ ast (2.4.3)
12
+ bigdecimal (4.0.1)
13
+ diff-lcs (1.6.2)
14
+ json (2.19.1)
15
+ json-schema (6.2.0)
16
+ addressable (~> 2.8)
17
+ bigdecimal (>= 3.1, < 5)
18
+ language_server-protocol (3.17.0.5)
19
+ lint_roller (1.1.0)
20
+ mcp (0.8.0)
21
+ json-schema (>= 4.1)
22
+ parallel (1.27.0)
23
+ parser (3.3.10.2)
24
+ ast (~> 2.4.1)
25
+ racc
26
+ prism (1.9.0)
27
+ public_suffix (7.0.5)
28
+ racc (1.8.1)
29
+ rainbow (3.1.1)
30
+ regexp_parser (2.11.3)
31
+ rspec (3.13.2)
32
+ rspec-core (~> 3.13.0)
33
+ rspec-expectations (~> 3.13.0)
34
+ rspec-mocks (~> 3.13.0)
35
+ rspec-core (3.13.6)
36
+ rspec-support (~> 3.13.0)
37
+ rspec-expectations (3.13.5)
38
+ diff-lcs (>= 1.2.0, < 2.0)
39
+ rspec-support (~> 3.13.0)
40
+ rspec-mocks (3.13.8)
41
+ diff-lcs (>= 1.2.0, < 2.0)
42
+ rspec-support (~> 3.13.0)
43
+ rspec-support (3.13.7)
44
+ rubocop (1.85.1)
45
+ json (~> 2.3)
46
+ language_server-protocol (~> 3.17.0.2)
47
+ lint_roller (~> 1.1.0)
48
+ mcp (~> 0.6)
49
+ parallel (~> 1.10)
50
+ parser (>= 3.3.0.2)
51
+ rainbow (>= 2.2.2, < 4.0)
52
+ regexp_parser (>= 2.9.3, < 3.0)
53
+ rubocop-ast (>= 1.49.0, < 2.0)
54
+ ruby-progressbar (~> 1.7)
55
+ unicode-display_width (>= 2.4.0, < 4.0)
56
+ rubocop-ast (1.49.1)
57
+ parser (>= 3.3.7.2)
58
+ prism (~> 1.7)
59
+ rubocop-rspec (3.9.0)
60
+ lint_roller (~> 1.1)
61
+ rubocop (~> 1.81)
62
+ ruby-progressbar (1.13.0)
63
+ unicode-display_width (3.2.0)
64
+ unicode-emoji (~> 4.1)
65
+ unicode-emoji (4.2.0)
66
+
67
+ PLATFORMS
68
+ arm64-darwin-25
69
+ ruby
70
+
71
+ DEPENDENCIES
72
+ lex-cognitive-grammar!
73
+ rspec (~> 3.13)
74
+ rubocop (~> 1.75)
75
+ rubocop-rspec
76
+
77
+ BUNDLED WITH
78
+ 2.6.9
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # lex-cognitive-grammar
2
+
3
+ Cognitive grammar construction network for brain-modeled agentic AI in the LegionIO ecosystem.
4
+
5
+ ## What It Does
6
+
7
+ Models the mental grammar through which meaning is assembled. Constructions are symbolic form-meaning units that activate with use and decay when dormant. Construals represent specific applications of constructions to scenes using cognitive operations (profiling, figure-ground, scope, perspective). Each use of a construction strengthens its activation via Exponential Moving Average. Once activation crosses the entrenchment threshold (0.8), the construction becomes automatic. A periodic decay pass prunes underused constructions from the network.
8
+
9
+ ## Usage
10
+
11
+ ```ruby
12
+ require 'legion/extensions/cognitive_grammar'
13
+
14
+ client = Legion::Extensions::CognitiveGrammar::Client.new
15
+
16
+ # Create a form-meaning construction
17
+ result = client.create_grammar_construction(
18
+ name: 'caused_motion',
19
+ form: '[Agent VERB Theme Path]',
20
+ meaning: 'agent causes theme to move along path',
21
+ domain: :motion
22
+ )
23
+ construction_id = result[:construction_id]
24
+
25
+ # Apply it to a scene (construal)
26
+ client.create_grammar_construal(
27
+ construction_id: construction_id,
28
+ scene: 'pushing the idea forward',
29
+ operation: :figure_ground,
30
+ prominence: :trajector
31
+ )
32
+
33
+ # Record a use — updates EMA activation
34
+ client.use_grammar_construction(construction_id: construction_id)
35
+ # => { success: true, before: 0.3, after: 0.37, entrenched: false }
36
+
37
+ # Check which constructions are entrenched
38
+ client.entrenched_constructions_report(limit: 10)
39
+ # => { success: true, constructions: [...] }
40
+
41
+ # Periodic decay maintenance
42
+ client.update_cognitive_grammar
43
+ # => { success: true, decayed: 1 }
44
+ ```
45
+
46
+ ## Development
47
+
48
+ ```bash
49
+ bundle install
50
+ bundle exec rspec
51
+ bundle exec rubocop
52
+ ```
53
+
54
+ ## License
55
+
56
+ MIT
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/legion/extensions/cognitive_grammar/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'lex-cognitive-grammar'
7
+ spec.version = Legion::Extensions::CognitiveGrammar::VERSION
8
+ spec.authors = ['Esity']
9
+ spec.email = ['matthewdiverson@gmail.com']
10
+
11
+ spec.summary = 'LEX Cognitive Grammar'
12
+ spec.description = 'Langacker-inspired cognitive grammar engine for LegionIO — construal operations, construction entrenchment, and meaning as construal'
13
+ spec.homepage = 'https://github.com/LegionIO/lex-cognitive-grammar'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.4'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/LegionIO/lex-cognitive-grammar'
19
+ spec.metadata['documentation_uri'] = 'https://github.com/LegionIO/lex-cognitive-grammar'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/LegionIO/lex-cognitive-grammar'
21
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/LegionIO/lex-cognitive-grammar/issues'
22
+ spec.metadata['rubygems_mfa_required'] = 'true'
23
+
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ end
27
+ spec.require_paths = ['lib']
28
+ spec.add_development_dependency 'legion-gaia'
29
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/cognitive_grammar/helpers/constants'
4
+ require 'legion/extensions/cognitive_grammar/helpers/construction'
5
+ require 'legion/extensions/cognitive_grammar/helpers/construal'
6
+ require 'legion/extensions/cognitive_grammar/helpers/grammar_engine'
7
+ require 'legion/extensions/cognitive_grammar/runners/cognitive_grammar'
8
+
9
+ module Legion
10
+ module Extensions
11
+ module CognitiveGrammar
12
+ class Client
13
+ include Runners::CognitiveGrammar
14
+
15
+ def initialize(**)
16
+ @engine = Helpers::GrammarEngine.new
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :engine
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveGrammar
6
+ module Helpers
7
+ module Constants
8
+ CONSTRUAL_OPERATIONS = %i[perspective prominence specificity scope dynamicity].freeze
9
+ PROMINENCE_TYPES = %i[figure ground].freeze
10
+ SPECIFICITY_LEVELS = %i[schematic intermediate detailed].freeze
11
+ SCOPE_LEVELS = %i[immediate local global].freeze
12
+ EXPRESSION_TYPES = %i[nominal relational clausal].freeze
13
+
14
+ ACTIVATION_LABELS = {
15
+ (0.8..) => :entrenched,
16
+ (0.6...0.8) => :conventional,
17
+ (0.4...0.6) => :familiar,
18
+ (0.2...0.4) => :novel,
19
+ (..0.2) => :ad_hoc
20
+ }.freeze
21
+
22
+ MAX_CONSTRUCTIONS = 200
23
+ MAX_CONSTRUALS = 500
24
+ MAX_HISTORY = 500
25
+
26
+ DEFAULT_ACTIVATION = 0.3
27
+ ACTIVATION_BOOST = 0.1
28
+ ACTIVATION_DECAY = 0.02
29
+ ENTRENCHMENT_THRESHOLD = 0.8
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module CognitiveGrammar
8
+ module Helpers
9
+ class Construal
10
+ include Constants
11
+
12
+ attr_reader :id, :scene, :perspective, :figure, :ground, :specificity,
13
+ :scope, :dynamicity, :construction_id, :created_at
14
+
15
+ def initialize(scene:, perspective:, figure:, ground:,
16
+ specificity: :intermediate, scope: :local,
17
+ dynamicity: 0.5, construction_id: nil)
18
+ @id = SecureRandom.uuid
19
+ @scene = scene
20
+ @perspective = perspective
21
+ @figure = figure
22
+ @ground = ground
23
+ @specificity = specificity.to_sym
24
+ @scope = scope.to_sym
25
+ @dynamicity = dynamicity.clamp(0.0, 1.0)
26
+ @construction_id = construction_id
27
+ @created_at = Time.now.utc
28
+ end
29
+
30
+ def prominent_element
31
+ @figure
32
+ end
33
+
34
+ def background_element
35
+ @ground
36
+ end
37
+
38
+ def detailed?
39
+ @specificity == :detailed
40
+ end
41
+
42
+ def global_scope?
43
+ @scope == :global
44
+ end
45
+
46
+ def to_h
47
+ {
48
+ id: @id,
49
+ scene: @scene,
50
+ perspective: @perspective,
51
+ figure: @figure,
52
+ ground: @ground,
53
+ specificity: @specificity,
54
+ scope: @scope,
55
+ dynamicity: @dynamicity,
56
+ construction_id: @construction_id,
57
+ created_at: @created_at
58
+ }
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+
5
+ module Legion
6
+ module Extensions
7
+ module CognitiveGrammar
8
+ module Helpers
9
+ class Construction
10
+ include Constants
11
+
12
+ attr_reader :id, :form, :meaning, :expression_type, :usage_count, :domain, :created_at
13
+ attr_accessor :activation
14
+
15
+ def initialize(form:, meaning:, expression_type:, domain:, activation: DEFAULT_ACTIVATION)
16
+ @id = SecureRandom.uuid
17
+ @form = form
18
+ @meaning = meaning
19
+ @expression_type = expression_type.to_sym
20
+ @activation = activation.clamp(0.0, 1.0)
21
+ @usage_count = 0
22
+ @domain = domain
23
+ @created_at = Time.now.utc
24
+ end
25
+
26
+ def use!
27
+ @usage_count += 1
28
+ @activation = [@activation + ACTIVATION_BOOST, 1.0].min.round(10)
29
+ self
30
+ end
31
+
32
+ def decay!
33
+ @activation = [@activation - ACTIVATION_DECAY, 0.0].max
34
+ self
35
+ end
36
+
37
+ def entrenched?
38
+ @activation >= ENTRENCHMENT_THRESHOLD
39
+ end
40
+
41
+ def activation_label
42
+ match = ACTIVATION_LABELS.find { |range, _| range.cover?(@activation) }
43
+ match ? match.last : :ad_hoc
44
+ end
45
+
46
+ def to_h
47
+ {
48
+ id: @id,
49
+ form: @form,
50
+ meaning: @meaning,
51
+ expression_type: @expression_type,
52
+ activation: @activation,
53
+ usage_count: @usage_count,
54
+ domain: @domain,
55
+ entrenched: entrenched?,
56
+ activation_label: activation_label,
57
+ created_at: @created_at
58
+ }
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveGrammar
6
+ module Helpers
7
+ class GrammarEngine
8
+ include Constants
9
+
10
+ def initialize
11
+ @constructions = {}
12
+ @construals = {}
13
+ end
14
+
15
+ def create_construction(form:, meaning:, expression_type:, domain:, activation: DEFAULT_ACTIVATION)
16
+ prune_constructions_if_needed
17
+ construction = Construction.new(
18
+ form: form,
19
+ meaning: meaning,
20
+ expression_type: expression_type,
21
+ domain: domain,
22
+ activation: activation
23
+ )
24
+ @constructions[construction.id] = construction
25
+ construction
26
+ end
27
+
28
+ def create_construal(scene:, perspective:, figure:, ground:,
29
+ specificity: :intermediate, scope: :local,
30
+ dynamicity: 0.5, construction_id: nil)
31
+ prune_construals_if_needed
32
+ construal = Construal.new(
33
+ scene: scene,
34
+ perspective: perspective,
35
+ figure: figure,
36
+ ground: ground,
37
+ specificity: specificity,
38
+ scope: scope,
39
+ dynamicity: dynamicity,
40
+ construction_id: construction_id
41
+ )
42
+ @construals[construal.id] = construal
43
+ construal
44
+ end
45
+
46
+ def use_construction(construction_id:)
47
+ construction = @constructions[construction_id]
48
+ return nil unless construction
49
+
50
+ construction.use!
51
+ end
52
+
53
+ def construals_for_scene(scene:)
54
+ @construals.values.select { |c| c.scene == scene }
55
+ end
56
+
57
+ def entrenched_constructions
58
+ @constructions.values.select(&:entrenched?)
59
+ end
60
+
61
+ def constructions_by_domain(domain:)
62
+ @constructions.values.select { |c| c.domain == domain }
63
+ end
64
+
65
+ def constructions_by_type(expression_type:)
66
+ type = expression_type.to_sym
67
+ @constructions.values.select { |c| c.expression_type == type }
68
+ end
69
+
70
+ def most_used(limit: 5)
71
+ @constructions.values.sort_by { |c| -c.usage_count }.first(limit)
72
+ end
73
+
74
+ def most_activated(limit: 5)
75
+ @constructions.values.sort_by { |c| -c.activation }.first(limit)
76
+ end
77
+
78
+ def decay_all
79
+ @constructions.each_value(&:decay!)
80
+ end
81
+
82
+ def prune_inactive
83
+ before = @constructions.size
84
+ @constructions.delete_if { |_, c| c.activation <= 0.05 }
85
+ before - @constructions.size
86
+ end
87
+
88
+ def to_h
89
+ {
90
+ constructions_count: @constructions.size,
91
+ construals_count: @construals.size,
92
+ entrenched_count: entrenched_constructions.size
93
+ }
94
+ end
95
+
96
+ private
97
+
98
+ def prune_constructions_if_needed
99
+ return if @constructions.size < MAX_CONSTRUCTIONS
100
+
101
+ oldest = @constructions.values.min_by(&:activation)
102
+ @constructions.delete(oldest.id) if oldest
103
+ end
104
+
105
+ def prune_construals_if_needed
106
+ return if @construals.size < MAX_CONSTRUALS
107
+
108
+ oldest = @construals.values.min_by(&:created_at)
109
+ @construals.delete(oldest.id) if oldest
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveGrammar
6
+ module Runners
7
+ module CognitiveGrammar
8
+ include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers) &&
9
+ Legion::Extensions::Helpers.const_defined?(:Lex)
10
+
11
+ def create_grammar_construction(form:, meaning:, expression_type:, domain:, **)
12
+ construction = engine.create_construction(
13
+ form: form,
14
+ meaning: meaning,
15
+ expression_type: expression_type,
16
+ domain: domain
17
+ )
18
+ Legion::Logging.debug "[cognitive_grammar] created construction form=#{form} type=#{expression_type} domain=#{domain}"
19
+ construction.to_h
20
+ end
21
+
22
+ def create_grammar_construal(scene:, perspective:, figure:, ground:, # rubocop:disable Metrics/ParameterLists
23
+ specificity: :intermediate, scope: :local,
24
+ dynamicity: 0.5, construction_id: nil, **)
25
+ construal = engine.create_construal(
26
+ scene: scene,
27
+ perspective: perspective,
28
+ figure: figure,
29
+ ground: ground,
30
+ specificity: specificity,
31
+ scope: scope,
32
+ dynamicity: dynamicity,
33
+ construction_id: construction_id
34
+ )
35
+ Legion::Logging.debug "[cognitive_grammar] created construal scene=#{scene} figure=#{figure}"
36
+ construal.to_h
37
+ end
38
+
39
+ def use_grammar_construction(construction_id:, **)
40
+ construction = engine.use_construction(construction_id: construction_id)
41
+ return { found: false, construction_id: construction_id } unless construction
42
+
43
+ msg = "[cognitive_grammar] used construction id=#{construction_id[0..7]} " \
44
+ "usage_count=#{construction.usage_count} activation=#{construction.activation.round(3)}"
45
+ Legion::Logging.debug msg
46
+ { found: true, construction: construction.to_h }
47
+ end
48
+
49
+ def construals_for_scene_report(scene:, **)
50
+ construals = engine.construals_for_scene(scene: scene)
51
+ Legion::Logging.debug "[cognitive_grammar] construals_for_scene scene=#{scene} count=#{construals.size}"
52
+ { scene: scene, count: construals.size, construals: construals.map(&:to_h) }
53
+ end
54
+
55
+ def entrenched_constructions_report(**)
56
+ constructions = engine.entrenched_constructions
57
+ Legion::Logging.debug "[cognitive_grammar] entrenched constructions count=#{constructions.size}"
58
+ { count: constructions.size, constructions: constructions.map(&:to_h) }
59
+ end
60
+
61
+ def constructions_by_domain_report(domain:, **)
62
+ constructions = engine.constructions_by_domain(domain: domain)
63
+ Legion::Logging.debug "[cognitive_grammar] constructions_by_domain domain=#{domain} count=#{constructions.size}"
64
+ { domain: domain, count: constructions.size, constructions: constructions.map(&:to_h) }
65
+ end
66
+
67
+ def most_used_constructions(limit: 5, **)
68
+ constructions = engine.most_used(limit: limit)
69
+ Legion::Logging.debug "[cognitive_grammar] most_used limit=#{limit} count=#{constructions.size}"
70
+ { limit: limit, count: constructions.size, constructions: constructions.map(&:to_h) }
71
+ end
72
+
73
+ def update_cognitive_grammar(**)
74
+ engine.decay_all
75
+ pruned = engine.prune_inactive
76
+ stats = engine.to_h
77
+ Legion::Logging.debug "[cognitive_grammar] update: pruned=#{pruned} remaining=#{stats[:constructions_count]}"
78
+ { pruned: pruned, stats: stats }
79
+ end
80
+
81
+ def cognitive_grammar_stats(**)
82
+ stats = engine.to_h
83
+ Legion::Logging.debug "[cognitive_grammar] stats constructions=#{stats[:constructions_count]} construals=#{stats[:construals_count]}"
84
+ stats
85
+ end
86
+
87
+ private
88
+
89
+ def engine
90
+ @engine ||= Helpers::GrammarEngine.new
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Extensions
5
+ module CognitiveGrammar
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/cognitive_grammar/version'
4
+ require 'legion/extensions/cognitive_grammar/helpers/constants'
5
+ require 'legion/extensions/cognitive_grammar/helpers/construction'
6
+ require 'legion/extensions/cognitive_grammar/helpers/construal'
7
+ require 'legion/extensions/cognitive_grammar/helpers/grammar_engine'
8
+ require 'legion/extensions/cognitive_grammar/runners/cognitive_grammar'
9
+ require 'legion/extensions/cognitive_grammar/client'
10
+
11
+ module Legion
12
+ module Extensions
13
+ module CognitiveGrammar
14
+ extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
15
+ end
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-cognitive-grammar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Esity
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: legion-gaia
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ description: Langacker-inspired cognitive grammar engine for LegionIO — construal
27
+ operations, construction entrenchment, and meaning as construal
28
+ email:
29
+ - matthewdiverson@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".github/workflows/ci.yml"
35
+ - ".gitignore"
36
+ - ".rspec"
37
+ - ".rubocop.yml"
38
+ - CLAUDE.md
39
+ - Gemfile
40
+ - Gemfile.lock
41
+ - README.md
42
+ - lex-cognitive-grammar.gemspec
43
+ - lib/legion/extensions/cognitive_grammar.rb
44
+ - lib/legion/extensions/cognitive_grammar/client.rb
45
+ - lib/legion/extensions/cognitive_grammar/helpers/constants.rb
46
+ - lib/legion/extensions/cognitive_grammar/helpers/construal.rb
47
+ - lib/legion/extensions/cognitive_grammar/helpers/construction.rb
48
+ - lib/legion/extensions/cognitive_grammar/helpers/grammar_engine.rb
49
+ - lib/legion/extensions/cognitive_grammar/runners/cognitive_grammar.rb
50
+ - lib/legion/extensions/cognitive_grammar/version.rb
51
+ homepage: https://github.com/LegionIO/lex-cognitive-grammar
52
+ licenses:
53
+ - MIT
54
+ metadata:
55
+ homepage_uri: https://github.com/LegionIO/lex-cognitive-grammar
56
+ source_code_uri: https://github.com/LegionIO/lex-cognitive-grammar
57
+ documentation_uri: https://github.com/LegionIO/lex-cognitive-grammar
58
+ changelog_uri: https://github.com/LegionIO/lex-cognitive-grammar
59
+ bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-grammar/issues
60
+ rubygems_mfa_required: 'true'
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '3.4'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubygems_version: 3.6.9
76
+ specification_version: 4
77
+ summary: LEX Cognitive Grammar
78
+ test_files: []