viv-compiler 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.
- viv_compiler/__init__.py +14 -0
- viv_compiler/__main__.py +3 -0
- viv_compiler/_samples/__init__.py +0 -0
- viv_compiler/_samples/smoke-test.viv +5 -0
- viv_compiler/api.py +58 -0
- viv_compiler/backports/__init__.py +1 -0
- viv_compiler/backports/backports.py +12 -0
- viv_compiler/cli.py +237 -0
- viv_compiler/config/__init__.py +1 -0
- viv_compiler/config/config.py +88 -0
- viv_compiler/core/__init__.py +5 -0
- viv_compiler/core/core.py +185 -0
- viv_compiler/core/importer.py +111 -0
- viv_compiler/core/postprocessor.py +749 -0
- viv_compiler/core/validator.py +915 -0
- viv_compiler/core/visitor.py +1188 -0
- viv_compiler/grammar/__init__.py +0 -0
- viv_compiler/grammar/viv.peg +228 -0
- viv_compiler/py.typed +1 -0
- viv_compiler/types/__init__.py +3 -0
- viv_compiler/types/content_public_schemas.py +420 -0
- viv_compiler/types/dsl_public_schemas.py +566 -0
- viv_compiler/types/internal_types.py +167 -0
- viv_compiler/utils/__init__.py +1 -0
- viv_compiler/utils/_version.py +2 -0
- viv_compiler/utils/utils.py +171 -0
- viv_compiler-0.1.0.dist-info/METADATA +284 -0
- viv_compiler-0.1.0.dist-info/RECORD +32 -0
- viv_compiler-0.1.0.dist-info/WHEEL +5 -0
- viv_compiler-0.1.0.dist-info/entry_points.txt +3 -0
- viv_compiler-0.1.0.dist-info/licenses/LICENSE +21 -0
- viv_compiler-0.1.0.dist-info/top_level.txt +1 -0
File without changes
|
@@ -0,0 +1,228 @@
|
|
1
|
+
// This is a specification of the syntax of the Viv action language, declared in a variant of extended Backus--Naur
|
2
|
+
// form (EBNF) that is associated with the parsing expression grammar (PEG) formalism. More specifically, it is in
|
3
|
+
// the format expected by the Arpeggio Python library (version 2.0.0).
|
4
|
+
|
5
|
+
|
6
|
+
// The top-level nonterminal combines include declarations with action and trope definitions, in any order
|
7
|
+
|
8
|
+
file = (include / trope / action)* EOF
|
9
|
+
|
10
|
+
|
11
|
+
// Include declaration
|
12
|
+
|
13
|
+
include = "include" filename
|
14
|
+
filename = '"' (!'"' ((r'(\w+)' / r'.')))* '"' /
|
15
|
+
"'" (!"'" ((r'(\w+)' / r'.')))* "'"
|
16
|
+
|
17
|
+
|
18
|
+
// Action definition
|
19
|
+
|
20
|
+
action = action_header action_body
|
21
|
+
action_header = special_action_tag? "action" name parent_action_declaration? ":"
|
22
|
+
parent_action_declaration = "from" name
|
23
|
+
action_body = (
|
24
|
+
(&"gloss" gloss)? /
|
25
|
+
(&"report" report)? /
|
26
|
+
(&"saliences" saliences)? /
|
27
|
+
(&"associations" associations)? /
|
28
|
+
(&"embargoes" embargoes)? /
|
29
|
+
(&"tags" tags_field / &"join" tags_field)? /
|
30
|
+
(&"roles" roles / &"join" roles)? /
|
31
|
+
(&"preconditions" preconditions / &"join" preconditions)? /
|
32
|
+
(&"scratch" scratch / &"join" scratch)? /
|
33
|
+
(&"effects" effects / &"join" effects)? /
|
34
|
+
(&"reactions" reactions / &"join" reactions)?
|
35
|
+
)#
|
36
|
+
|
37
|
+
// Trope definition
|
38
|
+
|
39
|
+
trope = "trope" name trope_role_names? ":" statements
|
40
|
+
trope_role_names = "with" name ("," name)*
|
41
|
+
|
42
|
+
|
43
|
+
// Main components of Viv definitions
|
44
|
+
|
45
|
+
special_action_tag = "special"
|
46
|
+
gloss = "gloss" ":" string
|
47
|
+
report = "report" ":" templated_text
|
48
|
+
tags_field = child_join_operator? "tags" ":" tags
|
49
|
+
tags = tag ("," tag)*
|
50
|
+
tag = token
|
51
|
+
roles = child_join_operator? "roles" ":" role+
|
52
|
+
role = role_renaming / (number_range? binding_rate_directive? role_name binding_pool_directive? ":" role_labels)
|
53
|
+
role_renaming = role_name "<<" role_name
|
54
|
+
number_range = number ("-" number)?
|
55
|
+
role_name = name ""
|
56
|
+
binding_pool_directive = binding_pool_from_directive / binding_pool_is_directive
|
57
|
+
binding_pool_from_directive = "from" expression
|
58
|
+
binding_pool_is_directive = "is" expression
|
59
|
+
role_labels = role_label ("," role_label)*
|
60
|
+
role_label = "initiator" / "partner" / "recipient" / "bystander" / "subject" / "location" /
|
61
|
+
"symbol" / "absent" / "action" / "item" / "precast" / build_directive
|
62
|
+
build_directive = "build" "(" build_directive_entity_recipe ")"
|
63
|
+
build_directive_entity_recipe = object
|
64
|
+
binding_rate_directive = chance_directive / mean_directive
|
65
|
+
chance_directive = "[" "-"? r"[0-9]+(\.[0-9]+)?" "%" "]"
|
66
|
+
mean_directive = "[" "~" "-"? r"[0-9]+(\.[0-9]+)?" "]"
|
67
|
+
preconditions = child_join_operator? "preconditions" ":" statements
|
68
|
+
child_join_operator = "join"
|
69
|
+
scratch = child_join_operator? "scratch" ":" statements
|
70
|
+
effects = child_join_operator? "effects" ":" statements
|
71
|
+
reactions = child_join_operator? "reactions" ":" (conditional / loop / reaction)+
|
72
|
+
reaction = "queue" reaction_action_name ":" reaction_options
|
73
|
+
reaction_action_name = name
|
74
|
+
reaction_options = (bindings / urgent? / priority? / kill_code? / when? / where? / abandonment_conditions?)#
|
75
|
+
bindings = "bindings" ":" binding+
|
76
|
+
binding = (name ":" reference) / loop
|
77
|
+
urgent = "urgent" ":" expression
|
78
|
+
priority = "priority" ":" expression
|
79
|
+
kill_code = "kill_code" ":" expression
|
80
|
+
where = "where" ":" expression
|
81
|
+
when = "when" (when_action_timestamp_anchor / when_hearing_timestamp_anchor) ":" time_expression
|
82
|
+
when_action_timestamp_anchor = "from action"
|
83
|
+
when_hearing_timestamp_anchor = "from hearing"
|
84
|
+
time_expression = time_statement ("," time_statement)?
|
85
|
+
time_statement = before_time_statement / after_time_statement / between_time_statement
|
86
|
+
before_time_statement = "before" (time_period / time)
|
87
|
+
after_time_statement = "after" (time_period / time)
|
88
|
+
between_time_statement = "between" time_period "and" time_period / "between" time "and" time
|
89
|
+
time_period = (number / number_word) ("minutes" / "hours" / "days" / "weeks" / "months" / "years" /
|
90
|
+
"minute" / "hour" / "day" / "week" / "month" / "year" )
|
91
|
+
number_word = "one" / "two" / "three" / "four" / "five" / "six" / "seven" / "eight" / "nine" /
|
92
|
+
"ten" / "eleven" / "twelve"
|
93
|
+
time = hh (":" mm)? ("pm" / "am" / "PM" / "AM")
|
94
|
+
hh = r"[0-9]{1,2}"
|
95
|
+
mm = r"[0-9]{2}"
|
96
|
+
abandonment_conditions = "abandon" ":" statements
|
97
|
+
saliences = child_join_operator? "saliences" saliences_default_value saliences_body?
|
98
|
+
saliences_default_value = "default" (enum / number)
|
99
|
+
saliences_body = ":" statement+
|
100
|
+
|
101
|
+
associations = child_join_operator? "associations" associations_default_value associations_body?
|
102
|
+
associations_default_value = "default" tags
|
103
|
+
associations_body = ":" associations_statements
|
104
|
+
associations_statements = associations_statement+
|
105
|
+
associations_statement = associations_conditional / associations_loop / tags
|
106
|
+
associations_conditional =
|
107
|
+
"if" condition ":"
|
108
|
+
associations_conditional_consequent
|
109
|
+
("else:" associations_conditional_alternative)?
|
110
|
+
"end"
|
111
|
+
associations_conditional_consequent = associations_scoped_statements ""
|
112
|
+
associations_conditional_alternative = associations_scoped_statements ""
|
113
|
+
associations_loop =
|
114
|
+
"loop" unary_expression "as" local_variable_reference ":"
|
115
|
+
associations_scoped_statements
|
116
|
+
"end"
|
117
|
+
associations_scoped_statements = (!"end" !"else:" associations_statement)+
|
118
|
+
|
119
|
+
embargoes = child_join_operator? "embargoes" ":" embargo+
|
120
|
+
embargo = embargo_roles? embargo_time_period embargo_location?
|
121
|
+
embargo_roles = !embargo_time_period role_name ("," role_name)*
|
122
|
+
embargo_time_period = ("for" time_period) / "forever"
|
123
|
+
embargo_location = "here" ""
|
124
|
+
trope_fit_expression = trope_fit_expression_args &"fits" "fits" name
|
125
|
+
trope_fit_expression_args = reference ("," reference)*
|
126
|
+
name = (!reserved r"[A-Za-z_][A-Za-z0-9\-_]*")
|
127
|
+
reserved = "loop" / "gloss" / "roles" / "preconditions" / "effects" / "reactions" / "saliences" /
|
128
|
+
"priority" / "kill_code" / "abandon" / "if" / "else" / "end" / "action" / "when" /
|
129
|
+
"where" / "associations" / "special" / "default" / "urgent" / "type" / "__causes__" /
|
130
|
+
"__groups__" / "__action__" / "join" / "tags" / "embargoes" / "here" / "include" /
|
131
|
+
"report" / "trope" / "fits" / "with" / "scratch"
|
132
|
+
|
133
|
+
|
134
|
+
// High-level language features
|
135
|
+
|
136
|
+
comment = r"\/\/[^\n]*"
|
137
|
+
role_reference = role_reference_sigil name
|
138
|
+
role_reference_sigil = "@"
|
139
|
+
local_variable_reference = local_variable_sigil name
|
140
|
+
local_variable_sigil = "$$"
|
141
|
+
global_variable_reference = global_variable_sigil name
|
142
|
+
global_variable_sigil = "$"
|
143
|
+
role_unpacking = role_unpacking_sigil name
|
144
|
+
role_unpacking_sigil = "*"
|
145
|
+
adapter_function_call = "~" name "(" args? ")" eval_fail_safe_marker?
|
146
|
+
args = expression ("," expression)*
|
147
|
+
statements = statement+
|
148
|
+
statement = conditional / loop / reaction / expression / literal
|
149
|
+
conditional = "if" condition ":" consequent ("else:" alternative)? "end"
|
150
|
+
condition = expression
|
151
|
+
consequent = scoped_statements ""
|
152
|
+
alternative = scoped_statements ""
|
153
|
+
scoped_statements = (!"end" !"else:" statement)+
|
154
|
+
loop = "loop" unary_expression "as" local_variable_reference ":" scoped_statements "end"
|
155
|
+
|
156
|
+
|
157
|
+
// General expressions
|
158
|
+
|
159
|
+
expression = assignment_expression / arithmetic_expression / logical_expression / unary_expression
|
160
|
+
assignment_expression = &"{" &assignment_lvalue_start "{" assignment_lvalue assignment_operator expression "}" /
|
161
|
+
assignment_lvalue assignment_operator expression
|
162
|
+
assignment_lvalue = role_anchored_reference / local_variable_anchored_reference
|
163
|
+
assignment_lvalue_start = role_reference_sigil / local_variable_sigil / global_variable_sigil
|
164
|
+
arithmetic_expression = "{" unary_expression arithmetic_operator expression "}" /
|
165
|
+
unary_expression arithmetic_operator expression
|
166
|
+
logical_expression = disjunction ''
|
167
|
+
disjunction = conjunction ("||" conjunction)* /
|
168
|
+
negation? "{" conjunction ("||" conjunction)+ "}" !"&&"
|
169
|
+
conjunction = ("{" expression "}" / relational_expression) ("&&" logical_expression)* /
|
170
|
+
negation? "{" ("{" expression "}" / relational_expression) ("&&" logical_expression)+ "}"
|
171
|
+
relational_expression = negation? "{" unary_expression relational_operator unary_expression "}" /
|
172
|
+
unary_expression relational_operator unary_expression /
|
173
|
+
unary_expression
|
174
|
+
unary_expression = negation? "{" simple_unary_expression "}" / negation? simple_unary_expression
|
175
|
+
simple_unary_expression = object / chance_expression / trope_fit_expression / adapter_function_call /
|
176
|
+
list / role_anchored_reference / local_variable_anchored_reference /
|
177
|
+
role_unpacking / literal
|
178
|
+
chance_expression = "-"? r"[0-9]+(\.[0-9]+)?" "%"
|
179
|
+
negation = "!"
|
180
|
+
assignment_operator = "+=" / "-=" / "*=" / "/=" / "=" / "append" / "remove"
|
181
|
+
relational_operator = "==" / "!=" / "<=" / ">=" / "<" / ">" / "in"
|
182
|
+
arithmetic_operator = "+" / "-" !">" / "*" / "/"
|
183
|
+
literal = enum / string / number / boolean / null_type
|
184
|
+
|
185
|
+
|
186
|
+
// References
|
187
|
+
|
188
|
+
reference = role_anchored_reference / local_variable_anchored_reference
|
189
|
+
role_anchored_reference = (role_reference / global_variable_reference) reference_path?
|
190
|
+
local_variable_anchored_reference = local_variable_reference reference_path?
|
191
|
+
reference_path = (reference_path_property_name / reference_path_pointer / reference_path_lookup)+
|
192
|
+
reference_path_property_name = "." property_name eval_fail_safe_marker?
|
193
|
+
reference_path_pointer = "->" property_name eval_fail_safe_marker?
|
194
|
+
reference_path_lookup = "[" expression "]" eval_fail_safe_marker?
|
195
|
+
property_name = r"[a-zA-Z0-9_]+"
|
196
|
+
eval_fail_safe_marker = "?" ""
|
197
|
+
|
198
|
+
|
199
|
+
// Data structures
|
200
|
+
|
201
|
+
list = "[" (expression ("," expression)*)? "]"
|
202
|
+
object = &"{" &object_key_start "{" (key_value_pair ("," key_value_pair)*)? "}"
|
203
|
+
object_key_start = '"' / "'" / r"[A-Za-z_]"
|
204
|
+
key_value_pair = key ":" value
|
205
|
+
key = string / bare_key
|
206
|
+
bare_key = r"[A-Za-z_][A-Za-z0-9_\-]*"
|
207
|
+
value = expression ''
|
208
|
+
|
209
|
+
|
210
|
+
// Literals
|
211
|
+
|
212
|
+
number = sign? r"[0-9]*" point r"[0-9]+" / sign? r"[0-9]+" point?
|
213
|
+
sign = '-' / '+'
|
214
|
+
point = "." / "." // There must be multiple rules to get the point itself to surface
|
215
|
+
string = '"' (!'"' (reference / space / character))* '"' /
|
216
|
+
"'" (!"'" (reference / space / character))* "'"
|
217
|
+
character = r'[^"\'{@*$]+'
|
218
|
+
space = r"[ \t]+"
|
219
|
+
token = !reserved r"[A-Za-z_][A-Za-z0-9\-_]*"
|
220
|
+
boolean = "true" / "false"
|
221
|
+
null_type = "null"
|
222
|
+
enum = ('-' / '+')? enum_token
|
223
|
+
enum_token = r'(##|#)[A-Za-z_][A-Za-z0-9\-_]*'
|
224
|
+
templated_text = '"' (!'"' template_gap / template_frame_component_double_quote)+ '"' /
|
225
|
+
"'" (!"'" template_gap / template_frame_component_single_quote)+ "'"
|
226
|
+
template_frame_component_double_quote = r'[^"{]+'
|
227
|
+
template_frame_component_single_quote = r"[^'{]+"
|
228
|
+
template_gap = "{" (reference / role_unpacking) "}"
|
viv_compiler/py.typed
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# PEP 561
|
@@ -0,0 +1,420 @@
|
|
1
|
+
"""Types associated with the higher-level concerns represented in Viv compiled content bundles.
|
2
|
+
|
3
|
+
This module and `dsl_public_schemas.py` together define the public, stable schema for Viv compiled
|
4
|
+
content bundles. The schemas capture the compiler's emitted JSON shapes, which are mirrored in the
|
5
|
+
corresponding runtime type definitions, assuming the same version number for the compiler and runtime.
|
6
|
+
As such, the schemas constitute a reliable contract between the compiler and any Viv runtime.
|
7
|
+
"""
|
8
|
+
|
9
|
+
from __future__ import annotations
|
10
|
+
|
11
|
+
from typing import Union, Literal, TYPE_CHECKING
|
12
|
+
from typing_extensions import TypedDict, NotRequired
|
13
|
+
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from .dsl_public_schemas import (
|
16
|
+
Enum,
|
17
|
+
EnumName,
|
18
|
+
Expression,
|
19
|
+
ExpressionDiscriminator,
|
20
|
+
FloatField,
|
21
|
+
IntField,
|
22
|
+
ListField,
|
23
|
+
ObjectField,
|
24
|
+
StringField,
|
25
|
+
TemplateStringField,
|
26
|
+
VariableName,
|
27
|
+
)
|
28
|
+
|
29
|
+
|
30
|
+
class CompiledContentBundle(TypedDict):
|
31
|
+
"""A content bundle in the format produced by the Viv compiler."""
|
32
|
+
# Trope definitions, keyed by name
|
33
|
+
tropes: dict[TropeName, TropeDefinition]
|
34
|
+
# Action definitions, keyed by name
|
35
|
+
actions: dict[ActionName, ActionDefinition]
|
36
|
+
# Metadata for the content bundle, which is currently used for validation purposes
|
37
|
+
meta: CompiledContentBundleMetadata
|
38
|
+
|
39
|
+
|
40
|
+
class CompiledContentBundleMetadata(TypedDict):
|
41
|
+
"""Metadata on the content bundle.
|
42
|
+
|
43
|
+
This metadata attaches a Viv version number to the content bundle, which guarantees
|
44
|
+
compatibility with any Viv runtime with the same version number.
|
45
|
+
|
46
|
+
The metadata here is also used to support validation during initialization of a target application's
|
47
|
+
Viv adapter by, e.g., confirming that any referenced enums and adapter functions actually exist.
|
48
|
+
"""
|
49
|
+
# The Viv compiler version at the time of compiling this content bundle. If this
|
50
|
+
# version number corresponds to the version number for a Viv runtime, the content
|
51
|
+
# bundle is guaranteed to be compatible with that runtime.
|
52
|
+
vivVersion: str
|
53
|
+
# An array containing the names of all enums referenced in the content bundle. This is
|
54
|
+
# used for validation during the initialization of a target application's Viv adapter.
|
55
|
+
referencedEnums: list[EnumName]
|
56
|
+
# An array containing the names of all adapter functions referenced in the
|
57
|
+
# content bundle. This is used for validation during the initialization of
|
58
|
+
# a target application's Viv adapter.
|
59
|
+
referencedFunctionNames: list[AdapterFunctionName]
|
60
|
+
|
61
|
+
|
62
|
+
# Unique name for an arbitrary function exposed in a target application's Viv adapter
|
63
|
+
AdapterFunctionName = str
|
64
|
+
|
65
|
+
|
66
|
+
class TropeDefinition(TypedDict):
|
67
|
+
"""A definition for a Viv trope (reusable bundle of conditions)."""
|
68
|
+
# The (unique) name of the trope
|
69
|
+
name: TropeName
|
70
|
+
# The parameters for the trope. These take entity references as arguments,
|
71
|
+
# allowing the conditions to refer to those entities.
|
72
|
+
params: list[TropeParamName]
|
73
|
+
# The ordered set of conditions composing the trope
|
74
|
+
conditions: list[Expression]
|
75
|
+
|
76
|
+
|
77
|
+
# A unique name for a trope
|
78
|
+
TropeName = str
|
79
|
+
|
80
|
+
# A unique trope parameter name
|
81
|
+
TropeParamName = str
|
82
|
+
|
83
|
+
|
84
|
+
class ActionDefinition(TypedDict):
|
85
|
+
"""A compiled definition for a Viv action."""
|
86
|
+
# The (unique) name of the action
|
87
|
+
name: ActionName
|
88
|
+
# Whether this action may only be targeted as a queued reaction (True if so)
|
89
|
+
special: bool
|
90
|
+
# Name of the parent action from which this one inherited, if any. This field is
|
91
|
+
# not currently used by the runtimes, but it can sometimes be useful for debugging.
|
92
|
+
parent: ActionName | None
|
93
|
+
# Tags on the action, whose purposes will depend on the target application
|
94
|
+
tags: ListField
|
95
|
+
# Mapping from the names of the roles associated with this action to their respective role definitions
|
96
|
+
roles: dict[RoleName, RoleDefinition]
|
97
|
+
# Definition for a simple templated string describing this action in a sentence or so
|
98
|
+
gloss: StringField | TemplateStringField | None
|
99
|
+
# Definition for a more detailed templated string describing this action in a paragraph or so
|
100
|
+
report: TemplateStringField | None
|
101
|
+
# Preconditions for the action, grouped by role name. A precondition is an expression that
|
102
|
+
# must hold (i.e., evaluate to a truthy value) in order for an action to be performed with
|
103
|
+
# a prospective cast.
|
104
|
+
preconditions: dict[RoleName, list[WrappedExpression]]
|
105
|
+
# An ordered set of expressions that prepare a set of temporary variables that may be referenced
|
106
|
+
# downstream in the action definition. These temporary variables can be referenced by an author
|
107
|
+
# using the `$` sigil, but this is syntactic sugar for `@this.scratch` — e.g., `$foo` is equivalent
|
108
|
+
# to `@this.scratch.foo`.
|
109
|
+
scratch: list[Expression]
|
110
|
+
# An ordered set of expressions that, when executed, cause updates to the target application state
|
111
|
+
effects: list[WrappedExpression]
|
112
|
+
# A set of expressions that each produce a reaction when evaluated. A reaction specifies an action that
|
113
|
+
# may be queued up for some time in the future, should an instance of the one at hand be performed.
|
114
|
+
reactions: list[WrappedExpression]
|
115
|
+
# Specifications for yielding numeric salience values for the action
|
116
|
+
saliences: Saliences
|
117
|
+
# Specifications for yielding subjective associations for the action
|
118
|
+
associations: Associations
|
119
|
+
# Embargo directives, which are authorial levers for controlling the frequency
|
120
|
+
# with which an action will be performed in the target application.
|
121
|
+
embargoes: list[EmbargoDeclaration]
|
122
|
+
# Definition for this role's initiator, copied from the `roles` field,
|
123
|
+
# where it also lives, into this top-level property as an optimization.
|
124
|
+
initiator: RoleDefinition
|
125
|
+
|
126
|
+
|
127
|
+
# A unique name for an action
|
128
|
+
ActionName = str
|
129
|
+
|
130
|
+
|
131
|
+
class RoleDefinition(TypedDict, total=False):
|
132
|
+
"""A definition for a role in a Viv action definition."""
|
133
|
+
# A name for this role, unique only within the associated action definition
|
134
|
+
name: RoleName
|
135
|
+
# The minimum number of entities to be cast into this role
|
136
|
+
min: int
|
137
|
+
# The maximum number of entities to be cast into this role
|
138
|
+
max: int
|
139
|
+
# If specified, the chance that a qualifying entity will be cast into the role. This field was
|
140
|
+
# first implemented to support a pattern of specifying how likely it is that a given nearby
|
141
|
+
# character will witness an action, which can be accomplished by defining a `bystander` role
|
142
|
+
# with a high `max` and a specified `chance` value. Chance values are always guaranteed to
|
143
|
+
# fall between `0.0` and `1.0`.
|
144
|
+
chance: float | None
|
145
|
+
# A mean on which to anchor a distribution from which will be sampled the number of entities
|
146
|
+
# to cast into the role. This distribution must also be parameterized by a `sd` value.
|
147
|
+
mean: float | None
|
148
|
+
# Standard deviation for a distribution from which will be sampled the number of entities
|
149
|
+
# to cast into the role. This distribution must also be parameterized by a `mean` value.
|
150
|
+
sd: float | None
|
151
|
+
# If specified, a directive specifying the pool of entities who may be cast into this role
|
152
|
+
# at a given point in time, given an initiator and possibly other prospective role bindings.
|
153
|
+
pool: BindingPool | None
|
154
|
+
# The name of this role's parent, if any, in the dependency tree that is used
|
155
|
+
# during role casting. This dependency tree is used to optimize this process.
|
156
|
+
parent: RoleName | None
|
157
|
+
# The names of this role's children, if any, in the dependency tree that is
|
158
|
+
# used during casting. This dependency tree is used to optimize this process.
|
159
|
+
children: list[RoleName]
|
160
|
+
# Whether a character must be cast in this role
|
161
|
+
character: bool
|
162
|
+
# Whether an item must be cast in this role
|
163
|
+
item: bool
|
164
|
+
# Whether another action must be cast in this role
|
165
|
+
action: bool
|
166
|
+
# Whether a location must be cast in this role
|
167
|
+
location: bool
|
168
|
+
# Whether a symbol (some kind of literal value) must be cast in this role
|
169
|
+
symbol: bool
|
170
|
+
# Whether an entity cast in this role is initiator of the associated action
|
171
|
+
initiator: bool
|
172
|
+
# Whether an entity cast in this role is a co-initiator of the associated action
|
173
|
+
partner: bool
|
174
|
+
# Whether an entity cast in this role is a recipient of the associated action
|
175
|
+
recipient: bool
|
176
|
+
# Whether an entity cast in this role is an uninvolved witness to the associated action
|
177
|
+
bystander: bool
|
178
|
+
# Whether an entity cast in this role is the subject of the associated action
|
179
|
+
subject: bool
|
180
|
+
# Whether an entity cast in this role is a character who is not physically present for the associated action
|
181
|
+
absent: bool
|
182
|
+
# Whether this role must be precast via reaction bindings. See Reaction docs for details
|
183
|
+
precast: bool
|
184
|
+
# Whether the entity cast in this role is to be constructed as a result of the
|
185
|
+
# associated action. Build roles are always accompanied by an entity recipe.
|
186
|
+
build: bool
|
187
|
+
# For `build` roles only, an expression that evaluates to the recipe for constructing an entity
|
188
|
+
# to be cast into the role. The format used here is completely dependent on the target application,
|
189
|
+
# but Viv allows authors to specify an arbitrary Viv object. When it's time to build a new entity,
|
190
|
+
# the entity recipe will be passed to the `buildEntity()` adapter function, which is tasked with
|
191
|
+
# actually constructing the entity.
|
192
|
+
entityRecipe: NotRequired[ObjectField]
|
193
|
+
|
194
|
+
|
195
|
+
# A name for an action role (unique only within its action definition)
|
196
|
+
RoleName = str
|
197
|
+
|
198
|
+
|
199
|
+
class BindingPool(TypedDict):
|
200
|
+
"""A directive specifying the pool of entities who may be cast into a role at a given
|
201
|
+
point in time, given an initiator and possibly other prospective role bindings.
|
202
|
+
"""
|
203
|
+
# The Viv expression that should evaluate to a binding pool
|
204
|
+
body: Expression
|
205
|
+
# Whether the binding pool is uncachable. A binding pool is cachable so long as the associated
|
206
|
+
# pool declaration does not reference a non-initiator role, in which case the role pool would
|
207
|
+
# have to be re-computed if the parent role[s] are re-cast (which never happens with an
|
208
|
+
# initiator role). When a binding pool is cached, it is not recomputed even as other
|
209
|
+
# non-initiator roles are re-cast.
|
210
|
+
uncachable: bool
|
211
|
+
|
212
|
+
|
213
|
+
class Reaction(TypedDict):
|
214
|
+
"""A Viv reaction expression.
|
215
|
+
|
216
|
+
A reaction specifies an action that may be queued up for some time in the future,
|
217
|
+
should an instance of the one at hand be performed.
|
218
|
+
"""
|
219
|
+
# Discriminator for Viv reaction expressions
|
220
|
+
type: Literal[ExpressionDiscriminator.REACTION]
|
221
|
+
# The actual expression value
|
222
|
+
value: ReactionValue
|
223
|
+
|
224
|
+
|
225
|
+
class ReactionValue(TypedDict):
|
226
|
+
"""A specification of the parameters defining a reaction."""
|
227
|
+
# The name of the target action, i.e., the one queued up by this reaction
|
228
|
+
actionName: ActionName
|
229
|
+
# Specification for how to precast entities in (a subset of) the roles of the target action
|
230
|
+
bindings: list[ReactionBinding]
|
231
|
+
# Parameterization of the reaction along various options
|
232
|
+
options: ReactionOptions
|
233
|
+
|
234
|
+
|
235
|
+
class ReactionBinding(TypedDict):
|
236
|
+
"""An expression specifying how to precast a particular role in a reaction's target action."""
|
237
|
+
# Discriminator for Viv binding expressions
|
238
|
+
type: Literal[ExpressionDiscriminator.BINDING]
|
239
|
+
# The actual expression value
|
240
|
+
value: ReactionBindingValue
|
241
|
+
|
242
|
+
|
243
|
+
class ReactionBindingValue(TypedDict):
|
244
|
+
"""Value of a binding expression."""
|
245
|
+
# The name of the role in the target action that will be precast via this binding
|
246
|
+
role: RoleName
|
247
|
+
# An expression that should evaluate to the entity to precast in the role associated with this binding
|
248
|
+
entity: Expression
|
249
|
+
|
250
|
+
|
251
|
+
class ReactionOptions(TypedDict, total=False):
|
252
|
+
"""A set of options parameterizing a reaction."""
|
253
|
+
# An expression that should evaluate to a boolean value indicating whether the reaction will queue its
|
254
|
+
# target action urgently. (The evaluated value will be cast to a boolean, so authors should be careful
|
255
|
+
# here.) Urgent actions receive the highest priority in action queueing.
|
256
|
+
urgent: Expression
|
257
|
+
# An expression that should evaluate to a numeric value specifying the priority of the queued
|
258
|
+
# action. Within a given queue group (urgent or non-urgent), queued actions are targeted in
|
259
|
+
# descending order of priority.
|
260
|
+
priority: Expression
|
261
|
+
# An expression that should evaluate to a string or number constituting a *kill code*. (If a number is
|
262
|
+
# produced, it will be coerced into a string, for use as an object key.) When a queued action is performed,
|
263
|
+
# its kill code (if any) is asserted, which causes all other queued actions with the same kill code to be
|
264
|
+
# dequeued. This supports an authoring pattern where multiple competing reaction alternatives are queued
|
265
|
+
# at the same time, each with the same kill code, where only the first one to be targeted successfully
|
266
|
+
# will actually be performed. As a concrete example, imagine a character who is punched by someone and
|
267
|
+
# whose personality is such that fighting back and running away would each be believable in their own
|
268
|
+
# right. Instead of selecting one exclusively, an author can queue both and let it play out by chance,
|
269
|
+
# with the winner dequeueing the others. Or they can queue multiple alternatives whose reaction options
|
270
|
+
# conditionalize the prospects, such that the evolving state of the storyworld will ultimately decide
|
271
|
+
# the winner. In each case, a kill code marks incompatibility between the alternatives, and in turn
|
272
|
+
# guarantees that at most one of them will ever be performed. See pp. 618--619 of my PhD thesis for an
|
273
|
+
# example of advanced usage of kill codes to coordinate and manage complex potential action sequences.
|
274
|
+
killCode: Expression | None
|
275
|
+
# An expression that should evaluate to a location, that being the specific location
|
276
|
+
# at which the queued action must be performed.
|
277
|
+
where: Expression | None
|
278
|
+
# A time expression constraining when exactly the queued action may be performed.
|
279
|
+
when: TemporalConstraints | None
|
280
|
+
# A set of expressions such that, if all of them hold (i.e., evaluate to a truthy value),
|
281
|
+
# the queued action will be dequeued.
|
282
|
+
abandonmentConditions: list[Expression]
|
283
|
+
|
284
|
+
|
285
|
+
class Saliences(TypedDict):
|
286
|
+
"""Specifications for determining a numeric salience score for the action that will be held
|
287
|
+
by a given character who experiences, observes, or otherwise learns about the action.
|
288
|
+
"""
|
289
|
+
# A specification for a default value to be used as a fallback for any character for
|
290
|
+
# which no `body` expressions hold. This will always be structured as a Viv enum,
|
291
|
+
# int, or float, where even the enum should resolve to a numeric value.
|
292
|
+
default: Union[Enum, IntField, FloatField]
|
293
|
+
# The name of the variable to which a character will be bound when computing a salience for
|
294
|
+
# them. This allows for evaluation of the body expressions, which may refer to this variable
|
295
|
+
# in order to do things like conditionalize salience based on the character at hand.
|
296
|
+
variable: VariableName
|
297
|
+
# An ordered array of Viv expressions that will each evaluate to a numeric value, as in the
|
298
|
+
# `default` property. These will be evaluated in turn, with the first numeric evaluated value
|
299
|
+
# being assigned as the character's salience. If no body expression evaluates to a numeric
|
300
|
+
# value, the default value will be used.
|
301
|
+
body: list[Expression]
|
302
|
+
|
303
|
+
|
304
|
+
class Associations(TypedDict):
|
305
|
+
"""Specifications for determining the subjective associations for the action that will be held
|
306
|
+
by a given character who experiences, observes, or otherwise learns about the action.
|
307
|
+
"""
|
308
|
+
# A specification for a default value to be used as a fallback for any character for which no
|
309
|
+
# `body` expressions hold. This will always be structured as a Viv list whose elements will be
|
310
|
+
# simple Viv string expressions.
|
311
|
+
default: ListField
|
312
|
+
# The name of the variable to which a character will be bound when computing associations for
|
313
|
+
# them. This allows for evaluation of the body expressions, which may refer to this variable
|
314
|
+
# in order to do things like conditionalize associations based on the character at hand.
|
315
|
+
variable: VariableName
|
316
|
+
# An ordered array of Viv expressions that will each evaluate to Viv lists containing simple
|
317
|
+
# Viv string expressions, as in the `default` property. These will be evaluated in turn, with
|
318
|
+
# all the results being concatenated together to compose the associations for the character
|
319
|
+
# at hand. If no body expression evaluates to a list value, the default value will be used.
|
320
|
+
body: list[Expression]
|
321
|
+
|
322
|
+
|
323
|
+
class EmbargoDeclaration(TypedDict):
|
324
|
+
"""An embargo declaration constraining the subsequent performance of an associated action."""
|
325
|
+
# Names for all the roles constituting the bindings over which this embargo holds. For instance,
|
326
|
+
# if two roles R1 and R2 were specified here, and if an action A was performed with bindings
|
327
|
+
# R1=[E1] and R2=[E2, E3], then this embargo would hold over all cases of A with any prospective
|
328
|
+
# bindings that cast E1 in R1 and *either* E2 and/or E3 in R2. Stated differently, the embargo
|
329
|
+
# holds if for all roles specified here, some subset overlaps between the embargo role bindings
|
330
|
+
# and the prospective role bindings. Often, an embargo will only specify an initiator.
|
331
|
+
roles: list[RoleName] | None
|
332
|
+
# Whether the embargo is permanent. If so, `period` will always be null, and exactly one of
|
333
|
+
# the fields is guaranteed to be truthy.
|
334
|
+
permanent: bool
|
335
|
+
# For an embargo that is not permanent, a specification of the time period over which the embargo
|
336
|
+
# will hold. If `period` is present, `permanent` will always be false, and exactly one of the fields
|
337
|
+
# is guaranteed to be truthy.
|
338
|
+
period: TimePeriod | None
|
339
|
+
# Whether the embargo holds only over a certain location, that being the location
|
340
|
+
# at which an instance of the associated action has just been performed.
|
341
|
+
here: bool
|
342
|
+
|
343
|
+
|
344
|
+
class TemporalConstraints(TypedDict, total=False):
|
345
|
+
"""A set of one or more temporal constraints, which an author specifies (in a reaction declaration)
|
346
|
+
to control the time at which a queued action may be performed.
|
347
|
+
"""
|
348
|
+
# Whether to anchor the temporal constraints in the timestamp of the action that directly triggered this
|
349
|
+
# reaction -- meaning the action whose definition included the reaction declaration -- as opposed to the
|
350
|
+
# current simulation timestamp. This distinction only matters for time-period constraints, and specifically
|
351
|
+
# for cases where a reaction is triggered because a character has learned about an action after the fact.
|
352
|
+
# In such cases, we need to know whether a time-period constraint like "between 1 year and 3 years" holds
|
353
|
+
# relative to the timestamp of the original action or relative to the time at which the character learned
|
354
|
+
# about the original action.
|
355
|
+
useActionTimestamp: bool
|
356
|
+
# If specified, a temporal constraint specifying an acceptable range between
|
357
|
+
# two points in time, where one end of the range may be open-ended.
|
358
|
+
timePeriod: TimePeriodRangeConstraint | None
|
359
|
+
# If specified, a temporal constraint specifying an acceptable range between
|
360
|
+
# two times of day, where one end of the range may be open-ended.
|
361
|
+
timeOfDay: TimeOfDayRangeConstraint | None
|
362
|
+
|
363
|
+
|
364
|
+
class TimePeriodRangeConstraint(TypedDict, total=False):
|
365
|
+
"""A temporal constraint specifying an acceptable range between two points in time.
|
366
|
+
"""
|
367
|
+
# The point in time at which the range opens. This is specified as a relative time period (e.g., `5 days`)
|
368
|
+
# that the target application can resolve at runtime into a point in time (by anchoring it relative to a
|
369
|
+
# given simulation timestamp). If no relative time period is specified here, the range is open on this end.
|
370
|
+
open: TimePeriod | None
|
371
|
+
# The point in time at which the range closes. This is specified as a relative time period (e.g., `5 days`)
|
372
|
+
# that the target application can resolve at runtime into a point in time (by anchoring it relative to a
|
373
|
+
# given simulation timestamp). If no relative time period is specified here, the range is open on this end.
|
374
|
+
close: TimePeriod | None
|
375
|
+
|
376
|
+
|
377
|
+
class TimePeriod(TypedDict):
|
378
|
+
"""A relative time period (e.g., "2 weeks") that the target application can resolve
|
379
|
+
at runtime into a point in time.
|
380
|
+
"""
|
381
|
+
# The number of time units -- e.g., `2` in `2 weeks`
|
382
|
+
amount: int
|
383
|
+
# The unit of time -- e.g., `weeks` in `2 weeks`
|
384
|
+
unit: TemporalConstraintTimeUnit
|
385
|
+
|
386
|
+
|
387
|
+
class TimeOfDayRangeConstraint(TypedDict, total=False):
|
388
|
+
"""A temporal constraint specifying an acceptable range between two times of day.
|
389
|
+
"""
|
390
|
+
# The time of day that opens the range marked acceptable by the temporal constraint. If no
|
391
|
+
# time of day is specified here, the range is open on this end. Note that the target
|
392
|
+
# application is tasked with determining whether a given time of day has passed.
|
393
|
+
open: TimeOfDay | None
|
394
|
+
# The time of day that closes the range marked acceptable by the temporal constraint. If no
|
395
|
+
# time of day is specified here, the range is open on this end. Note that the target
|
396
|
+
# application is tasked with determining whether a given time of day has passed.
|
397
|
+
close: TimeOfDay | None
|
398
|
+
|
399
|
+
|
400
|
+
class TimeOfDay(TypedDict):
|
401
|
+
"""A specified time of day."""
|
402
|
+
# The hour of day
|
403
|
+
hour: int
|
404
|
+
# The minute of the hour of day
|
405
|
+
minute: int
|
406
|
+
|
407
|
+
|
408
|
+
# Enum containing the valid temporal-constraint time units
|
409
|
+
TemporalConstraintTimeUnit = Literal["minutes", "hours", "days", "weeks", "months", "years"]
|
410
|
+
|
411
|
+
|
412
|
+
class WrappedExpression(TypedDict):
|
413
|
+
"""A Viv expression wrapped with an array containing the names of all roles that it references.
|
414
|
+
|
415
|
+
These reference lists are used for various optimizations.
|
416
|
+
"""
|
417
|
+
# The actual Viv expression that is being wrapped
|
418
|
+
body: Expression
|
419
|
+
# Names of the roles referenced in the Viv expression
|
420
|
+
references: list[RoleName]
|