bead 0.1.0__py3-none-any.whl
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.
- bead/__init__.py +11 -0
- bead/__main__.py +11 -0
- bead/active_learning/__init__.py +15 -0
- bead/active_learning/config.py +231 -0
- bead/active_learning/loop.py +566 -0
- bead/active_learning/models/__init__.py +24 -0
- bead/active_learning/models/base.py +852 -0
- bead/active_learning/models/binary.py +910 -0
- bead/active_learning/models/categorical.py +943 -0
- bead/active_learning/models/cloze.py +862 -0
- bead/active_learning/models/forced_choice.py +956 -0
- bead/active_learning/models/free_text.py +773 -0
- bead/active_learning/models/lora.py +365 -0
- bead/active_learning/models/magnitude.py +835 -0
- bead/active_learning/models/multi_select.py +795 -0
- bead/active_learning/models/ordinal_scale.py +811 -0
- bead/active_learning/models/peft_adapter.py +155 -0
- bead/active_learning/models/random_effects.py +639 -0
- bead/active_learning/selection.py +354 -0
- bead/active_learning/strategies.py +391 -0
- bead/active_learning/trainers/__init__.py +26 -0
- bead/active_learning/trainers/base.py +210 -0
- bead/active_learning/trainers/data_collator.py +172 -0
- bead/active_learning/trainers/dataset_utils.py +261 -0
- bead/active_learning/trainers/huggingface.py +304 -0
- bead/active_learning/trainers/lightning.py +324 -0
- bead/active_learning/trainers/metrics.py +424 -0
- bead/active_learning/trainers/mixed_effects.py +551 -0
- bead/active_learning/trainers/model_wrapper.py +509 -0
- bead/active_learning/trainers/registry.py +104 -0
- bead/adapters/__init__.py +11 -0
- bead/adapters/huggingface.py +61 -0
- bead/behavioral/__init__.py +116 -0
- bead/behavioral/analytics.py +646 -0
- bead/behavioral/extraction.py +343 -0
- bead/behavioral/merging.py +343 -0
- bead/cli/__init__.py +11 -0
- bead/cli/active_learning.py +513 -0
- bead/cli/active_learning_commands.py +779 -0
- bead/cli/completion.py +359 -0
- bead/cli/config.py +624 -0
- bead/cli/constraint_builders.py +286 -0
- bead/cli/deployment.py +859 -0
- bead/cli/deployment_trials.py +493 -0
- bead/cli/deployment_ui.py +332 -0
- bead/cli/display.py +378 -0
- bead/cli/items.py +960 -0
- bead/cli/items_factories.py +776 -0
- bead/cli/list_constraints.py +714 -0
- bead/cli/lists.py +490 -0
- bead/cli/main.py +430 -0
- bead/cli/models.py +877 -0
- bead/cli/resource_loaders.py +621 -0
- bead/cli/resources.py +1036 -0
- bead/cli/shell.py +356 -0
- bead/cli/simulate.py +840 -0
- bead/cli/templates.py +1158 -0
- bead/cli/training.py +1080 -0
- bead/cli/utils.py +614 -0
- bead/cli/workflow.py +1273 -0
- bead/config/__init__.py +68 -0
- bead/config/active_learning.py +1009 -0
- bead/config/config.py +192 -0
- bead/config/defaults.py +118 -0
- bead/config/deployment.py +217 -0
- bead/config/env.py +147 -0
- bead/config/item.py +45 -0
- bead/config/list.py +193 -0
- bead/config/loader.py +149 -0
- bead/config/logging.py +42 -0
- bead/config/model.py +49 -0
- bead/config/paths.py +46 -0
- bead/config/profiles.py +320 -0
- bead/config/resources.py +47 -0
- bead/config/serialization.py +210 -0
- bead/config/simulation.py +206 -0
- bead/config/template.py +238 -0
- bead/config/validation.py +267 -0
- bead/data/__init__.py +65 -0
- bead/data/base.py +87 -0
- bead/data/identifiers.py +97 -0
- bead/data/language_codes.py +61 -0
- bead/data/metadata.py +270 -0
- bead/data/range.py +123 -0
- bead/data/repository.py +358 -0
- bead/data/serialization.py +249 -0
- bead/data/timestamps.py +89 -0
- bead/data/validation.py +349 -0
- bead/data_collection/__init__.py +11 -0
- bead/data_collection/jatos.py +223 -0
- bead/data_collection/merger.py +154 -0
- bead/data_collection/prolific.py +198 -0
- bead/deployment/__init__.py +5 -0
- bead/deployment/distribution.py +402 -0
- bead/deployment/jatos/__init__.py +1 -0
- bead/deployment/jatos/api.py +200 -0
- bead/deployment/jatos/exporter.py +210 -0
- bead/deployment/jspsych/__init__.py +9 -0
- bead/deployment/jspsych/biome.json +44 -0
- bead/deployment/jspsych/config.py +411 -0
- bead/deployment/jspsych/generator.py +598 -0
- bead/deployment/jspsych/package.json +51 -0
- bead/deployment/jspsych/pnpm-lock.yaml +2141 -0
- bead/deployment/jspsych/randomizer.py +299 -0
- bead/deployment/jspsych/src/lib/list-distributor.test.ts +327 -0
- bead/deployment/jspsych/src/lib/list-distributor.ts +1282 -0
- bead/deployment/jspsych/src/lib/randomizer.test.ts +232 -0
- bead/deployment/jspsych/src/lib/randomizer.ts +367 -0
- bead/deployment/jspsych/src/plugins/cloze-dropdown.ts +252 -0
- bead/deployment/jspsych/src/plugins/forced-choice.ts +265 -0
- bead/deployment/jspsych/src/plugins/plugins.test.ts +141 -0
- bead/deployment/jspsych/src/plugins/rating.ts +248 -0
- bead/deployment/jspsych/src/slopit/index.ts +9 -0
- bead/deployment/jspsych/src/types/jatos.d.ts +256 -0
- bead/deployment/jspsych/src/types/jspsych.d.ts +228 -0
- bead/deployment/jspsych/templates/experiment.css +1 -0
- bead/deployment/jspsych/templates/experiment.js.template +289 -0
- bead/deployment/jspsych/templates/index.html +51 -0
- bead/deployment/jspsych/templates/randomizer.js +241 -0
- bead/deployment/jspsych/templates/randomizer.js.template +313 -0
- bead/deployment/jspsych/trials.py +723 -0
- bead/deployment/jspsych/tsconfig.json +23 -0
- bead/deployment/jspsych/tsup.config.ts +30 -0
- bead/deployment/jspsych/ui/__init__.py +1 -0
- bead/deployment/jspsych/ui/components.py +383 -0
- bead/deployment/jspsych/ui/styles.py +411 -0
- bead/dsl/__init__.py +80 -0
- bead/dsl/ast.py +168 -0
- bead/dsl/context.py +178 -0
- bead/dsl/errors.py +71 -0
- bead/dsl/evaluator.py +570 -0
- bead/dsl/grammar.lark +81 -0
- bead/dsl/parser.py +231 -0
- bead/dsl/stdlib.py +929 -0
- bead/evaluation/__init__.py +13 -0
- bead/evaluation/convergence.py +485 -0
- bead/evaluation/interannotator.py +398 -0
- bead/items/__init__.py +40 -0
- bead/items/adapters/__init__.py +70 -0
- bead/items/adapters/anthropic.py +224 -0
- bead/items/adapters/api_utils.py +167 -0
- bead/items/adapters/base.py +216 -0
- bead/items/adapters/google.py +259 -0
- bead/items/adapters/huggingface.py +1074 -0
- bead/items/adapters/openai.py +323 -0
- bead/items/adapters/registry.py +202 -0
- bead/items/adapters/sentence_transformers.py +224 -0
- bead/items/adapters/togetherai.py +309 -0
- bead/items/binary.py +515 -0
- bead/items/cache.py +558 -0
- bead/items/categorical.py +593 -0
- bead/items/cloze.py +757 -0
- bead/items/constructor.py +784 -0
- bead/items/forced_choice.py +413 -0
- bead/items/free_text.py +681 -0
- bead/items/generation.py +432 -0
- bead/items/item.py +396 -0
- bead/items/item_template.py +787 -0
- bead/items/magnitude.py +573 -0
- bead/items/multi_select.py +621 -0
- bead/items/ordinal_scale.py +569 -0
- bead/items/scoring.py +448 -0
- bead/items/validation.py +723 -0
- bead/lists/__init__.py +30 -0
- bead/lists/balancer.py +263 -0
- bead/lists/constraints.py +1067 -0
- bead/lists/experiment_list.py +286 -0
- bead/lists/list_collection.py +378 -0
- bead/lists/partitioner.py +1141 -0
- bead/lists/stratification.py +254 -0
- bead/participants/__init__.py +73 -0
- bead/participants/collection.py +699 -0
- bead/participants/merging.py +312 -0
- bead/participants/metadata_spec.py +491 -0
- bead/participants/models.py +276 -0
- bead/resources/__init__.py +29 -0
- bead/resources/adapters/__init__.py +19 -0
- bead/resources/adapters/base.py +104 -0
- bead/resources/adapters/cache.py +128 -0
- bead/resources/adapters/glazing.py +508 -0
- bead/resources/adapters/registry.py +117 -0
- bead/resources/adapters/unimorph.py +796 -0
- bead/resources/classification.py +856 -0
- bead/resources/constraint_builders.py +329 -0
- bead/resources/constraints.py +165 -0
- bead/resources/lexical_item.py +223 -0
- bead/resources/lexicon.py +744 -0
- bead/resources/loaders.py +209 -0
- bead/resources/template.py +441 -0
- bead/resources/template_collection.py +707 -0
- bead/resources/template_generation.py +349 -0
- bead/simulation/__init__.py +29 -0
- bead/simulation/annotators/__init__.py +15 -0
- bead/simulation/annotators/base.py +175 -0
- bead/simulation/annotators/distance_based.py +135 -0
- bead/simulation/annotators/lm_based.py +114 -0
- bead/simulation/annotators/oracle.py +182 -0
- bead/simulation/annotators/random.py +181 -0
- bead/simulation/dsl_extension/__init__.py +3 -0
- bead/simulation/noise_models/__init__.py +13 -0
- bead/simulation/noise_models/base.py +42 -0
- bead/simulation/noise_models/random_noise.py +82 -0
- bead/simulation/noise_models/systematic.py +132 -0
- bead/simulation/noise_models/temperature.py +86 -0
- bead/simulation/runner.py +144 -0
- bead/simulation/strategies/__init__.py +23 -0
- bead/simulation/strategies/base.py +123 -0
- bead/simulation/strategies/binary.py +103 -0
- bead/simulation/strategies/categorical.py +123 -0
- bead/simulation/strategies/cloze.py +224 -0
- bead/simulation/strategies/forced_choice.py +127 -0
- bead/simulation/strategies/free_text.py +105 -0
- bead/simulation/strategies/magnitude.py +116 -0
- bead/simulation/strategies/multi_select.py +129 -0
- bead/simulation/strategies/ordinal_scale.py +131 -0
- bead/templates/__init__.py +27 -0
- bead/templates/adapters/__init__.py +17 -0
- bead/templates/adapters/base.py +128 -0
- bead/templates/adapters/cache.py +178 -0
- bead/templates/adapters/huggingface.py +312 -0
- bead/templates/combinatorics.py +103 -0
- bead/templates/filler.py +605 -0
- bead/templates/renderers.py +177 -0
- bead/templates/resolver.py +178 -0
- bead/templates/strategies.py +1806 -0
- bead/templates/streaming.py +195 -0
- bead-0.1.0.dist-info/METADATA +212 -0
- bead-0.1.0.dist-info/RECORD +231 -0
- bead-0.1.0.dist-info/WHEEL +4 -0
- bead-0.1.0.dist-info/entry_points.txt +2 -0
- bead-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"""Constraint builder commands for bead CLI.
|
|
2
|
+
|
|
3
|
+
This module provides commands for creating constraints for template slot filling
|
|
4
|
+
using three types: extensional (value whitelists), intensional (feature-based
|
|
5
|
+
expressions), and relational (cross-slot constraints).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import click
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
|
|
15
|
+
from bead.cli.utils import print_error, print_info, print_success
|
|
16
|
+
from bead.resources.constraints import Constraint
|
|
17
|
+
|
|
18
|
+
console = Console()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@click.command()
|
|
22
|
+
@click.argument("output_file", type=click.Path(path_type=Path))
|
|
23
|
+
@click.option(
|
|
24
|
+
"--type",
|
|
25
|
+
"constraint_type",
|
|
26
|
+
type=click.Choice(["extensional", "intensional", "relational"]),
|
|
27
|
+
required=True,
|
|
28
|
+
help="Type of constraint to create",
|
|
29
|
+
)
|
|
30
|
+
@click.option(
|
|
31
|
+
"--slot",
|
|
32
|
+
help="Slot name for single-slot constraints (extensional, intensional)",
|
|
33
|
+
)
|
|
34
|
+
@click.option(
|
|
35
|
+
"--expression",
|
|
36
|
+
help="DSL expression for intensional constraints (e.g., \"self.pos == 'VERB'\")",
|
|
37
|
+
)
|
|
38
|
+
@click.option(
|
|
39
|
+
"--relation",
|
|
40
|
+
help='DSL expression for relational constraints (e.g., "a.number == b.number")',
|
|
41
|
+
)
|
|
42
|
+
@click.option(
|
|
43
|
+
"--values-file",
|
|
44
|
+
type=click.Path(exists=True, path_type=Path),
|
|
45
|
+
help="File with values for extensional constraints (one value per line)",
|
|
46
|
+
)
|
|
47
|
+
@click.option(
|
|
48
|
+
"--values",
|
|
49
|
+
help="Comma-separated values for extensional constraints",
|
|
50
|
+
)
|
|
51
|
+
@click.option(
|
|
52
|
+
"--context-var-name",
|
|
53
|
+
default="allowed_values",
|
|
54
|
+
help="Context variable name for extensional constraints (default: allowed_values)",
|
|
55
|
+
)
|
|
56
|
+
@click.option(
|
|
57
|
+
"--description",
|
|
58
|
+
help="Human-readable description of the constraint",
|
|
59
|
+
)
|
|
60
|
+
@click.option(
|
|
61
|
+
"--prop-name",
|
|
62
|
+
default="lemma",
|
|
63
|
+
help="Property to check for extensional constraints (default: lemma)",
|
|
64
|
+
)
|
|
65
|
+
@click.pass_context
|
|
66
|
+
def create_constraint(
|
|
67
|
+
ctx: click.Context,
|
|
68
|
+
output_file: Path,
|
|
69
|
+
constraint_type: str,
|
|
70
|
+
slot: str | None,
|
|
71
|
+
expression: str | None,
|
|
72
|
+
relation: str | None,
|
|
73
|
+
values_file: Path | None,
|
|
74
|
+
values: str | None,
|
|
75
|
+
context_var_name: str,
|
|
76
|
+
description: str | None,
|
|
77
|
+
prop_name: str,
|
|
78
|
+
) -> None:
|
|
79
|
+
r"""Create a constraint for template slot filling.
|
|
80
|
+
|
|
81
|
+
Supports three types of constraints:
|
|
82
|
+
|
|
83
|
+
\b
|
|
84
|
+
1. EXTENSIONAL: Whitelist of allowed values
|
|
85
|
+
$ bead resources create-constraint constraints.jsonl \
|
|
86
|
+
--type extensional \
|
|
87
|
+
--slot verb \
|
|
88
|
+
--values "walk,run,jump" \
|
|
89
|
+
--description "Motion verbs"
|
|
90
|
+
|
|
91
|
+
\b
|
|
92
|
+
2. INTENSIONAL: Feature-based DSL expression
|
|
93
|
+
$ bead resources create-constraint constraints.jsonl \
|
|
94
|
+
--type intensional \
|
|
95
|
+
--slot verb \
|
|
96
|
+
--expression "self.pos == 'VERB' and self.features.tense == 'past'" \
|
|
97
|
+
--description "Past tense verbs"
|
|
98
|
+
|
|
99
|
+
\b
|
|
100
|
+
3. RELATIONAL: Cross-slot agreement
|
|
101
|
+
$ bead resources create-constraint constraints.jsonl \
|
|
102
|
+
--type relational \
|
|
103
|
+
--relation "subject.features.number == verb.features.number" \
|
|
104
|
+
--description "Subject-verb agreement"
|
|
105
|
+
|
|
106
|
+
Parameters
|
|
107
|
+
----------
|
|
108
|
+
ctx : click.Context
|
|
109
|
+
Click context object.
|
|
110
|
+
output_file : Path
|
|
111
|
+
Path to output constraints file (JSONL).
|
|
112
|
+
constraint_type : str
|
|
113
|
+
Type of constraint (extensional, intensional, relational).
|
|
114
|
+
slot : str | None
|
|
115
|
+
Slot name for single-slot constraints.
|
|
116
|
+
expression : str | None
|
|
117
|
+
DSL expression for intensional constraints.
|
|
118
|
+
relation : str | None
|
|
119
|
+
DSL expression for relational constraints.
|
|
120
|
+
values_file : Path | None
|
|
121
|
+
File with values for extensional constraints.
|
|
122
|
+
values : str | None
|
|
123
|
+
Comma-separated values for extensional constraints.
|
|
124
|
+
context_var_name : str
|
|
125
|
+
Context variable name for extensional constraints.
|
|
126
|
+
description : str | None
|
|
127
|
+
Description of the constraint.
|
|
128
|
+
prop_name : str
|
|
129
|
+
Property to check for extensional constraints.
|
|
130
|
+
|
|
131
|
+
Examples
|
|
132
|
+
--------
|
|
133
|
+
# Extensional constraint from file
|
|
134
|
+
$ bead resources create-constraint constraints.jsonl \\
|
|
135
|
+
--type extensional \\
|
|
136
|
+
--slot verb \\
|
|
137
|
+
--values-file motion_verbs.txt \\
|
|
138
|
+
--description "Motion verbs only"
|
|
139
|
+
|
|
140
|
+
# Extensional constraint from values
|
|
141
|
+
$ bead resources create-constraint constraints.jsonl \\
|
|
142
|
+
--type extensional \\
|
|
143
|
+
--slot noun \\
|
|
144
|
+
--values "cat,dog,bird" \\
|
|
145
|
+
--prop-name lemma
|
|
146
|
+
|
|
147
|
+
# Intensional constraint
|
|
148
|
+
$ bead resources create-constraint constraints.jsonl \\
|
|
149
|
+
--type intensional \\
|
|
150
|
+
--slot verb \\
|
|
151
|
+
--expression "self.pos == 'VERB' and self.features.number == 'singular'"
|
|
152
|
+
|
|
153
|
+
# Relational constraint
|
|
154
|
+
$ bead resources create-constraint constraints.jsonl \\
|
|
155
|
+
--type relational \\
|
|
156
|
+
--relation "det.lemma != 'a' or noun.features.number == 'singular'" \\
|
|
157
|
+
--description "Article-noun agreement"
|
|
158
|
+
"""
|
|
159
|
+
try:
|
|
160
|
+
constraint: Constraint | None = None
|
|
161
|
+
|
|
162
|
+
if constraint_type == "extensional":
|
|
163
|
+
# Validate required parameters
|
|
164
|
+
if not values_file and not values:
|
|
165
|
+
print_error("Extensional constraints require --values-file or --values")
|
|
166
|
+
ctx.exit(1)
|
|
167
|
+
|
|
168
|
+
if not slot:
|
|
169
|
+
print_error("Extensional constraints require --slot")
|
|
170
|
+
ctx.exit(1)
|
|
171
|
+
|
|
172
|
+
# Load values
|
|
173
|
+
value_set: set[str]
|
|
174
|
+
if values_file:
|
|
175
|
+
print_info(f"Loading values from {values_file}")
|
|
176
|
+
with open(values_file, encoding="utf-8") as f:
|
|
177
|
+
value_set = {line.strip() for line in f if line.strip()}
|
|
178
|
+
else:
|
|
179
|
+
assert values is not None
|
|
180
|
+
value_set = {v.strip() for v in values.split(",") if v.strip()}
|
|
181
|
+
|
|
182
|
+
if not value_set:
|
|
183
|
+
print_error("No values provided")
|
|
184
|
+
ctx.exit(1)
|
|
185
|
+
|
|
186
|
+
# Create constraint
|
|
187
|
+
# Expression uses 'self' for single-slot constraints
|
|
188
|
+
expr = f"self.{prop_name} in {context_var_name}"
|
|
189
|
+
constraint = Constraint(
|
|
190
|
+
expression=expr,
|
|
191
|
+
context={context_var_name: value_set},
|
|
192
|
+
description=description
|
|
193
|
+
or f"Allowed {prop_name} values for {slot}: {len(value_set)} values",
|
|
194
|
+
)
|
|
195
|
+
print_success(
|
|
196
|
+
f"Created extensional constraint for '{slot}' "
|
|
197
|
+
f"with {len(value_set)} values"
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
elif constraint_type == "intensional":
|
|
201
|
+
# Validate required parameters
|
|
202
|
+
if not expression:
|
|
203
|
+
print_error("Intensional constraints require --expression")
|
|
204
|
+
ctx.exit(1)
|
|
205
|
+
|
|
206
|
+
if not slot:
|
|
207
|
+
print_info(
|
|
208
|
+
"No --slot specified; constraint will apply to template level"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
# Validate expression starts with 'self.' for slot-level constraints
|
|
212
|
+
if slot and not expression.startswith("self."):
|
|
213
|
+
print_error(
|
|
214
|
+
f"Intensional expression for slot '{slot}' must start with 'self.' "
|
|
215
|
+
f"to refer to the slot filler.\n\n"
|
|
216
|
+
f"Example: self.pos == 'VERB' and self.features.tense == 'past'"
|
|
217
|
+
)
|
|
218
|
+
ctx.exit(1)
|
|
219
|
+
|
|
220
|
+
# Create constraint
|
|
221
|
+
constraint = Constraint(
|
|
222
|
+
expression=expression,
|
|
223
|
+
description=description or f"Intensional constraint: {expression}",
|
|
224
|
+
)
|
|
225
|
+
print_success(
|
|
226
|
+
f"Created intensional constraint{' for slot ' + slot if slot else ''}"
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
elif constraint_type == "relational":
|
|
230
|
+
# Validate required parameters
|
|
231
|
+
if not relation:
|
|
232
|
+
print_error("Relational constraints require --relation")
|
|
233
|
+
ctx.exit(1)
|
|
234
|
+
|
|
235
|
+
# Validate expression does NOT start with 'self.' (multi-slot)
|
|
236
|
+
if relation.startswith("self."):
|
|
237
|
+
print_error(
|
|
238
|
+
"Relational constraints are multi-slot; do not use 'self.'.\n\n"
|
|
239
|
+
"Use slot names as variables instead.\n\n"
|
|
240
|
+
"Example: subject.features.number == verb.features.number"
|
|
241
|
+
)
|
|
242
|
+
ctx.exit(1)
|
|
243
|
+
|
|
244
|
+
# Create constraint
|
|
245
|
+
constraint = Constraint(
|
|
246
|
+
expression=relation,
|
|
247
|
+
description=description or f"Relational constraint: {relation}",
|
|
248
|
+
)
|
|
249
|
+
print_success("Created relational constraint")
|
|
250
|
+
|
|
251
|
+
else:
|
|
252
|
+
print_error(f"Unknown constraint type: {constraint_type}")
|
|
253
|
+
ctx.exit(1)
|
|
254
|
+
|
|
255
|
+
# Save constraint to JSONL
|
|
256
|
+
assert constraint is not None
|
|
257
|
+
output_file.parent.mkdir(parents=True, exist_ok=True)
|
|
258
|
+
|
|
259
|
+
# Append to file if it exists, create new file otherwise
|
|
260
|
+
mode = "a" if output_file.exists() else "w"
|
|
261
|
+
with open(output_file, mode, encoding="utf-8") as f:
|
|
262
|
+
f.write(constraint.model_dump_json() + "\n")
|
|
263
|
+
|
|
264
|
+
print_info(f"Constraint written to: {output_file}")
|
|
265
|
+
|
|
266
|
+
# Show example usage
|
|
267
|
+
if constraint_type == "extensional":
|
|
268
|
+
console.print("\n[cyan]Usage in template:[/cyan]")
|
|
269
|
+
console.print(
|
|
270
|
+
f" Add to Slot(name='{slot}', constraints=[...loaded from file...])"
|
|
271
|
+
)
|
|
272
|
+
elif constraint_type == "intensional":
|
|
273
|
+
console.print("\n[cyan]Usage in template:[/cyan]")
|
|
274
|
+
if slot:
|
|
275
|
+
console.print(
|
|
276
|
+
f" Add to Slot(name='{slot}', constraints=[...from file...])"
|
|
277
|
+
)
|
|
278
|
+
else:
|
|
279
|
+
console.print(" Add to Template.constraints=[...loaded from file...]")
|
|
280
|
+
elif constraint_type == "relational":
|
|
281
|
+
console.print("\n[cyan]Usage in template:[/cyan]")
|
|
282
|
+
console.print(" Add to Template.constraints=[...loaded from file...]")
|
|
283
|
+
|
|
284
|
+
except Exception as e:
|
|
285
|
+
print_error(f"Failed to create constraint: {e}")
|
|
286
|
+
ctx.exit(1)
|