prete 2.5.1__tar.gz
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.
- prete-2.5.1/.claude/settings.local.json +5 -0
- prete-2.5.1/.editorconfig +19 -0
- prete-2.5.1/.github/workflows/ci.yml +17 -0
- prete-2.5.1/.gitignore +80 -0
- prete-2.5.1/.mcp.json +11 -0
- prete-2.5.1/CHANGELOG.md +151 -0
- prete-2.5.1/LICENSE +21 -0
- prete-2.5.1/PKG-INFO +503 -0
- prete-2.5.1/README.md +472 -0
- prete-2.5.1/images/pRETE-logo-small.png +0 -0
- prete-2.5.1/images/pRETE-logo.png +0 -0
- prete-2.5.1/pyproject.toml +79 -0
- prete-2.5.1/src/examples/__init__.py +0 -0
- prete-2.5.1/src/examples/declarative/__init__.py +0 -0
- prete-2.5.1/src/examples/declarative/aggregation_prl.py +59 -0
- prete-2.5.1/src/examples/declarative/blocks_world_prl.py +57 -0
- prete-2.5.1/src/examples/declarative/compact_patterns_prl.py +40 -0
- prete-2.5.1/src/examples/declarative/disjunction_prl.py +47 -0
- prete-2.5.1/src/examples/declarative/domain.py +15 -0
- prete-2.5.1/src/examples/declarative/event_stream_prl.py +54 -0
- prete-2.5.1/src/examples/declarative/existence_check_prl.py +48 -0
- prete-2.5.1/src/examples/declarative/family_tree_prl.py +57 -0
- prete-2.5.1/src/examples/declarative/fraud_detection_prl.py +52 -0
- prete-2.5.1/src/examples/declarative/identity_key_prl.py +60 -0
- prete-2.5.1/src/examples/declarative/imported_types_prl.py +40 -0
- prete-2.5.1/src/examples/declarative/inheritance_prl.py +40 -0
- prete-2.5.1/src/examples/declarative/loan_application_prl.py +70 -0
- prete-2.5.1/src/examples/declarative/negation_prl.py +55 -0
- prete-2.5.1/src/examples/declarative/prl/aggregation.prl +16 -0
- prete-2.5.1/src/examples/declarative/prl/blocks_world.prl +26 -0
- prete-2.5.1/src/examples/declarative/prl/compact_patterns.prl +19 -0
- prete-2.5.1/src/examples/declarative/prl/disjunction.prl +18 -0
- prete-2.5.1/src/examples/declarative/prl/event_stream.prl +16 -0
- prete-2.5.1/src/examples/declarative/prl/existence_check.prl +17 -0
- prete-2.5.1/src/examples/declarative/prl/family_tree.prl +30 -0
- prete-2.5.1/src/examples/declarative/prl/fraud_detection.prl +24 -0
- prete-2.5.1/src/examples/declarative/prl/identity_key.prl +14 -0
- prete-2.5.1/src/examples/declarative/prl/imported_types.prl +11 -0
- prete-2.5.1/src/examples/declarative/prl/inheritance.prl +19 -0
- prete-2.5.1/src/examples/declarative/prl/loan_application.prl +36 -0
- prete-2.5.1/src/examples/declarative/prl/negation.prl +19 -0
- prete-2.5.1/src/examples/declarative/prl/self_modify.prl +15 -0
- prete-2.5.1/src/examples/declarative/prl/sharing.prl +35 -0
- prete-2.5.1/src/examples/declarative/prl/temperature_alarm.prl +17 -0
- prete-2.5.1/src/examples/declarative/prl/universal.prl +19 -0
- prete-2.5.1/src/examples/declarative/self_modify_prl.py +47 -0
- prete-2.5.1/src/examples/declarative/sharing_prl.py +58 -0
- prete-2.5.1/src/examples/declarative/temperature_alarm_prl.py +42 -0
- prete-2.5.1/src/examples/declarative/universal_prl.py +56 -0
- prete-2.5.1/src/examples/programmatic/__init__.py +0 -0
- prete-2.5.1/src/examples/programmatic/blocks_world.py +111 -0
- prete-2.5.1/src/examples/programmatic/family_tree.py +103 -0
- prete-2.5.1/src/examples/programmatic/fraud_detection.py +109 -0
- prete-2.5.1/src/examples/programmatic/loan_application.py +130 -0
- prete-2.5.1/src/examples/programmatic/negation.py +103 -0
- prete-2.5.1/src/examples/programmatic/sharing.py +149 -0
- prete-2.5.1/src/examples/programmatic/temperature_alarm.py +93 -0
- prete-2.5.1/src/rete/__init__.py +52 -0
- prete-2.5.1/src/rete/alpha.py +127 -0
- prete-2.5.1/src/rete/beta.py +899 -0
- prete-2.5.1/src/rete/condition.py +146 -0
- prete-2.5.1/src/rete/engine.py +186 -0
- prete-2.5.1/src/rete/fact.py +44 -0
- prete-2.5.1/src/rete/network.py +597 -0
- prete-2.5.1/src/rete/prl.py +834 -0
- prete-2.5.1/src/rete/prl_ast.py +276 -0
- prete-2.5.1/src/rete/prl_lexer.py +209 -0
- prete-2.5.1/src/rete/prl_parser.py +617 -0
- prete-2.5.1/tests/test_alpha.py +259 -0
- prete-2.5.1/tests/test_beta.py +1441 -0
- prete-2.5.1/tests/test_engine.py +499 -0
- prete-2.5.1/tests/test_examples.py +255 -0
- prete-2.5.1/tests/test_fact.py +80 -0
- prete-2.5.1/tests/test_integration.py +314 -0
- prete-2.5.1/tests/test_network.py +917 -0
- prete-2.5.1/tests/test_pattern.py +220 -0
- prete-2.5.1/tests/test_prl.py +1035 -0
- prete-2.5.1/tests/test_prl_ast.py +517 -0
- prete-2.5.1/tests/test_prl_compiler.py +954 -0
- prete-2.5.1/tests/test_prl_lexer.py +487 -0
- prete-2.5.1/tests/test_prl_parser.py +842 -0
- prete-2.5.1/tests/test_ul.py +400 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
insert_final_newline = true
|
|
7
|
+
trim_trailing_whitespace = true
|
|
8
|
+
|
|
9
|
+
[*.py]
|
|
10
|
+
indent_style = space
|
|
11
|
+
indent_size = 4
|
|
12
|
+
max_line_length = 88
|
|
13
|
+
|
|
14
|
+
[*.{prl,ebnf,md,toml,cfg,ini}]
|
|
15
|
+
indent_style = space
|
|
16
|
+
indent_size = 2
|
|
17
|
+
|
|
18
|
+
[Makefile]
|
|
19
|
+
indent_style = tab
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
test:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
strategy:
|
|
9
|
+
matrix:
|
|
10
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with:
|
|
15
|
+
python-version: ${{ matrix.python-version }}
|
|
16
|
+
- run: pip install -e ".[dev]"
|
|
17
|
+
- run: pytest --cov
|
prete-2.5.1/.gitignore
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
.idea/
|
|
2
|
+
.obsidian/
|
|
3
|
+
plan/
|
|
4
|
+
reference/
|
|
5
|
+
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*$py.class
|
|
9
|
+
*.so
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
*.manifest
|
|
29
|
+
*.spec
|
|
30
|
+
pip-log.txt
|
|
31
|
+
pip-delete-this-directory.txt
|
|
32
|
+
htmlcov/
|
|
33
|
+
.tox/
|
|
34
|
+
.nox/
|
|
35
|
+
.coverage
|
|
36
|
+
.coverage.*
|
|
37
|
+
.cache
|
|
38
|
+
nosetests.xml
|
|
39
|
+
coverage.xml
|
|
40
|
+
*.cover
|
|
41
|
+
*.py,cover
|
|
42
|
+
.hypothesis/
|
|
43
|
+
.pytest_cache/
|
|
44
|
+
cover/
|
|
45
|
+
*.mo
|
|
46
|
+
*.pot
|
|
47
|
+
*.log
|
|
48
|
+
local_settings.py
|
|
49
|
+
db.sqlite3
|
|
50
|
+
db.sqlite3-journal
|
|
51
|
+
instance/
|
|
52
|
+
.webassets-cache
|
|
53
|
+
.scrapy
|
|
54
|
+
docs/_build/
|
|
55
|
+
.pybuilder/
|
|
56
|
+
target/
|
|
57
|
+
.ipynb_checkpoints
|
|
58
|
+
profile_default/
|
|
59
|
+
ipython_config.py
|
|
60
|
+
__pypackages__/
|
|
61
|
+
celerybeat-schedule
|
|
62
|
+
celerybeat.pid
|
|
63
|
+
*.sage.py
|
|
64
|
+
.env
|
|
65
|
+
.venv
|
|
66
|
+
env/
|
|
67
|
+
venv/
|
|
68
|
+
ENV/
|
|
69
|
+
env.bak/
|
|
70
|
+
venv.bak/
|
|
71
|
+
.spyderproject
|
|
72
|
+
.spyproject
|
|
73
|
+
.ropeproject
|
|
74
|
+
/site
|
|
75
|
+
.mypy_cache/
|
|
76
|
+
.dmypy.json
|
|
77
|
+
dmypy.json
|
|
78
|
+
.pyre/
|
|
79
|
+
.pytype/
|
|
80
|
+
cython_debug/
|
prete-2.5.1/.mcp.json
ADDED
prete-2.5.1/CHANGELOG.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [2.5.1] — 2026-06-21
|
|
11
|
+
|
|
12
|
+
**Test coverage.**
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- Test suite expanded from 59 missed lines to 11 (99.17% coverage); remaining
|
|
16
|
+
11 misses are intentional (error-raising guards and structural dead code).
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## [2.5.0] — 2026-06-21
|
|
21
|
+
|
|
22
|
+
**Extending API change — PRL extra features.**
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- `extends` keyword in `declare` blocks — type inheritance via Python MRO;
|
|
26
|
+
parent-type patterns fire for child-type facts via `isinstance`.
|
|
27
|
+
- `@key` field tag — generates identity-aware `__eq__` / `__hash__` on declared
|
|
28
|
+
types using only the annotated key fields.
|
|
29
|
+
- Positional and named constraint shorthand — `TypeName(v1, v2)` and
|
|
30
|
+
`TypeName(field=v)` in patterns, resolved against declaration order at
|
|
31
|
+
compile time.
|
|
32
|
+
- `@no-loop` rule tag — alias for the existing `no-loop: true` attribute;
|
|
33
|
+
prevents a rule from re-activating on its own WM modifications.
|
|
34
|
+
- `import` / `from … import` / `from … import … as` — self-contained `.prl`
|
|
35
|
+
files that declare their own type dependencies; `types` dict in `load_prl`
|
|
36
|
+
becomes optional.
|
|
37
|
+
- `or` disjunction — single PRL rule with K LHS branches compiles to K
|
|
38
|
+
`Production` objects sharing the same RHS closure.
|
|
39
|
+
- `forall(P, Q)` — universal quantification, rewritten by the compiler to
|
|
40
|
+
`NccGroup([P, negated_Q])`.
|
|
41
|
+
- `exists Pattern(…)` — new `ExistsNode` in `beta.py`; fires once per
|
|
42
|
+
matching left context regardless of right-fact count.
|
|
43
|
+
- `@role(event)`, `@timestamp`, `@duration`, `@expires` — synchronous
|
|
44
|
+
logical-clock CEP model; events are auto-retracted when
|
|
45
|
+
`timestamp + expires < logical_clock`.
|
|
46
|
+
- `accumulate(inner; $result: fn; constraint)` — new `AccumulateNode` in
|
|
47
|
+
`beta.py` with incremental per-left-token state for `sum`, `count`, `min`,
|
|
48
|
+
`max`, `collectList`.
|
|
49
|
+
- New example `.prl` files and companion Python drivers for all extra features
|
|
50
|
+
(`src/examples/prl/inheritance.prl`, `identity_key.prl`,
|
|
51
|
+
`compact_patterns.prl`, `self_modify.prl`, `imported_types.prl`,
|
|
52
|
+
`disjunction.prl`, `universal.prl`, `existence_check.prl`,
|
|
53
|
+
`event_stream.prl`, `aggregation.prl`).
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
- `src/rete/prl_ast.py` — `DeclareDecl` gains `extends` and `tags` fields;
|
|
57
|
+
`FieldDecl` and `RuleDecl` gain `tags`; new AST nodes: `Tag`, `ImportDecl`,
|
|
58
|
+
`OrGroup`, `ForallNode`, `AccumulateNode` (AST).
|
|
59
|
+
- `src/rete/prl_lexer.py` — new keywords: `extends`, `import`, `from`, `as`,
|
|
60
|
+
`or`, `forall`, `exists`, `accumulate`; new `AT` token type.
|
|
61
|
+
- `src/rete/prl_parser.py` — tag parsing, `extends`, all import forms,
|
|
62
|
+
`or` / `forall` / `exists` / `accumulate` conditions.
|
|
63
|
+
- `src/rete/prl.py` — compiler handles all new AST nodes; topological sort
|
|
64
|
+
for `extends`; `__prl_meta__` dict on generated types for tag semantics.
|
|
65
|
+
- `src/rete/beta.py` — `ExistsNode`, `AccumulateNode`.
|
|
66
|
+
- `src/rete/condition.py` — `Pattern.exists`, `AccumulateSpec`.
|
|
67
|
+
- `src/rete/network.py` — wires `ExistsNode` / `AccumulateNode`.
|
|
68
|
+
- `src/rete/fact.py` — `Fact.timestamp` field for CEP.
|
|
69
|
+
- `src/rete/engine.py` — `logical_clock`, `advance_clock()`, `_expire_events()`.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## [2.1.0] — 2026-06-20
|
|
74
|
+
|
|
75
|
+
**Extending API change — pRETE Rule Language (PRL) parser added.**
|
|
76
|
+
|
|
77
|
+
### Added
|
|
78
|
+
- `rete.prl.load_prl(text, types, engine)` — parses PRL source into
|
|
79
|
+
`(dict[str, type], list[Production])` ready for the RETE engine.
|
|
80
|
+
- `src/rete/prl_lexer.py` — tokenizer for PRL source text.
|
|
81
|
+
- `src/rete/prl_ast.py` — frozen AST dataclasses (`FieldDecl`, `DeclareDecl`,
|
|
82
|
+
`BindConstraint`, `CompareConstraint`, `PatternNode`, `NccPatternGroup`,
|
|
83
|
+
`RuleDecl`, `ProgramNode`).
|
|
84
|
+
- `src/rete/prl_parser.py` — hand-written recursive-descent parser.
|
|
85
|
+
- `src/rete/prl.py` — compiler (AST → `Pattern` / `NccGroup` / `Production`)
|
|
86
|
+
and `load_prl()` entry point.
|
|
87
|
+
- `.prl` program files for all seven bundled examples
|
|
88
|
+
(`src/examples/prl/*.prl`).
|
|
89
|
+
- PRL-powered companion drivers for all seven examples
|
|
90
|
+
(`src/examples/*_prl.py`).
|
|
91
|
+
- Per-step unit tests: `test_prl_lexer.py`, `test_prl_ast.py`,
|
|
92
|
+
`test_prl_parser.py`, `test_prl_compiler.py`.
|
|
93
|
+
- Full-pipeline integration tests: `test_prl.py`.
|
|
94
|
+
|
|
95
|
+
### Changed
|
|
96
|
+
- `src/rete/__init__.py` — `load_prl` added to public re-exports and `__all__`.
|
|
97
|
+
|
|
98
|
+
### Notes
|
|
99
|
+
- The engine, network, alpha, and beta modules are **unchanged**.
|
|
100
|
+
- PRL is a strict subset of Drools Rule Language (DRL 8.x); see
|
|
101
|
+
`reference/prl-grammar.ebnf` for the full grammar.
|
|
102
|
+
- `salience` is parsed and preserved on `RuleDecl` (default 0) but not yet
|
|
103
|
+
wired into `InferenceEngine`'s conflict-set strategy.
|
|
104
|
+
- The regex-based `drl.py` prototype is superseded by `prl.py` and will be
|
|
105
|
+
removed in a future release.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## [2.0.0] — 2026-06-19
|
|
110
|
+
|
|
111
|
+
**Breaking API change — triple model replaced by Plain Old Python Objects (POPOs).**
|
|
112
|
+
|
|
113
|
+
### Added
|
|
114
|
+
- `Fact(obj)` — wraps any Python object as a working-memory element.
|
|
115
|
+
- `Pattern(type_, alpha_tests, join_tests, bindings, negated)` — replaces
|
|
116
|
+
`Condition`; matches by type then by callable field tests.
|
|
117
|
+
- `JoinSpec(attr_of_fact, var_name)` — compile-time cross-fact variable
|
|
118
|
+
reference declared in `Pattern.join_tests`.
|
|
119
|
+
- `Token.bindings: dict[str, Any]` — named variable bindings carried by
|
|
120
|
+
each partial match (replaces positional `token.wmes[i]` access).
|
|
121
|
+
- `InferenceEngine.update_fact(fact)` — Drools-style `modify`: retracts
|
|
122
|
+
and re-asserts a mutated fact so the network stays in sync.
|
|
123
|
+
- New examples: `loan_application.py`, `temperature_alarm.py`,
|
|
124
|
+
`family_tree.py`, `fraud_detection.py`.
|
|
125
|
+
|
|
126
|
+
### Removed
|
|
127
|
+
- `WME(id, attribute, value)` — replaced by `Fact(obj)`.
|
|
128
|
+
- `Condition(id_test, attribute_test, value_test)` — replaced by `Pattern`.
|
|
129
|
+
- `WILDCARD` constant — no longer needed; omit the field from `alpha_tests`.
|
|
130
|
+
- `add_wme` / `remove_wme` on `ReteNetwork` and `InferenceEngine` —
|
|
131
|
+
replaced by `add_fact` / `remove_fact`.
|
|
132
|
+
- `AlphaNode` trie — replaced by a single predicate per `AlphaMemory` and
|
|
133
|
+
type-indexed dispatch in `RootNode`.
|
|
134
|
+
|
|
135
|
+
### Changed
|
|
136
|
+
- `Token.wmes` → `Token.facts`.
|
|
137
|
+
- Alpha network now dispatches by MRO, so a `Dog` fact activates a
|
|
138
|
+
`Pattern(type_=Animal)`.
|
|
139
|
+
- Alpha memory sharing is keyed by `(type_, tuple(id(fn) for fn in alpha_tests))`;
|
|
140
|
+
stable function references (not inline lambdas) are required for sharing.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## [1.0.1] — prior
|
|
145
|
+
|
|
146
|
+
Incremental fixes to the v1.0.0 triple-based engine.
|
|
147
|
+
|
|
148
|
+
## [1.0.0] — prior
|
|
149
|
+
|
|
150
|
+
Initial release: triple `(id, attribute, value)` WME model, full Doorenbos
|
|
151
|
+
algorithm with right/left unlinking and NCC support.
|
prete-2.5.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stefano Bragaglia
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|