xbtm 0.1.0__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.
- xbtm-0.1.0/.gitignore +25 -0
- xbtm-0.1.0/.python-version +1 -0
- xbtm-0.1.0/LICENSE +21 -0
- xbtm-0.1.0/PKG-INFO +119 -0
- xbtm-0.1.0/README.md +97 -0
- xbtm-0.1.0/docs/dsl-spec.md +168 -0
- xbtm-0.1.0/docs/validation.md +419 -0
- xbtm-0.1.0/pyproject.toml +60 -0
- xbtm-0.1.0/src/xbtm/__init__.py +1 -0
- xbtm-0.1.0/src/xbtm/main.py +219 -0
- xbtm-0.1.0/src/xbtm/validation.py +277 -0
- xbtm-0.1.0/tests/test_parse.py +23 -0
- xbtm-0.1.0/tests/test_text.py +23 -0
- xbtm-0.1.0/tests/test_trials.py +23 -0
- xbtm-0.1.0/tests/test_validation.py +76 -0
- xbtm-0.1.0/uv.lock +651 -0
xbtm-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Python bytecode and caches
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
|
|
5
|
+
# Virtual environments
|
|
6
|
+
.venv/
|
|
7
|
+
venv/
|
|
8
|
+
env/
|
|
9
|
+
|
|
10
|
+
# Packaging artifacts
|
|
11
|
+
build/
|
|
12
|
+
dist/
|
|
13
|
+
*.egg-info/
|
|
14
|
+
|
|
15
|
+
# Test and coverage output
|
|
16
|
+
.pytest_cache/
|
|
17
|
+
.coverage
|
|
18
|
+
htmlcov/
|
|
19
|
+
|
|
20
|
+
# Editor and operating-system files
|
|
21
|
+
.vscode/
|
|
22
|
+
.idea/
|
|
23
|
+
.DS_Store
|
|
24
|
+
Thumbs.db
|
|
25
|
+
.ruff_cache/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
xbtm-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Imagination12357
|
|
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.
|
xbtm-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: xbtm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: XbTm (X-base Target Mapping) is a tool and DSL for generating canonical, entropy-efficient mappings from an x-way random source to an m-way target choice.
|
|
5
|
+
Project-URL: Repository, https://github.com/Imagination12357/xbtm
|
|
6
|
+
Project-URL: Issues, https://github.com/Imagination12357/xbtm/issues
|
|
7
|
+
Author: Imagination12357
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: dsl,entropy,probability,random,random-generation,rejection-sampling
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Requires-Dist: numpy>=2.0.0
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
XbTm (X-base Target Mapping) is a tool and DSL for generating canonical, entropy-efficient mappings from an x-way random source to an m-way target choice.
|
|
24
|
+
|
|
25
|
+
`xbtm` is a DSL for deterministically exploring and visualizing ways to emulate a uniform random generator with `target` outcomes using one with `base` outcomes.
|
|
26
|
+
|
|
27
|
+
## DSL format
|
|
28
|
+
|
|
29
|
+
A complete program combines a header and a body with a colon.
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
X{base}T{target}:{body}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`base` and `target` are natural numbers. When `target` is at least 2, `base` must also be at least 2. When `target` is 1, `base` may be 1 because there is no outcome to choose between.
|
|
36
|
+
|
|
37
|
+
Every body starts at the ordinary state `1`.
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
X2T5:1>2>4>8=5|3>6=5|(1)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## States and termination
|
|
44
|
+
|
|
45
|
+
- `n`: An ordinary, newly visited state `n`, written as a natural number.
|
|
46
|
+
- `(n)`: A reference state that returns to the previously visited state `n`. A reference state terminates the body.
|
|
47
|
+
- `!`: A termination marker indicating that the current ordinary state exactly equals `target`. The implementation represents it as an operator token for convenience.
|
|
48
|
+
|
|
49
|
+
Thus, a body starts at an ordinary state, repeats transitions, and ends with either a reference state or `!`.
|
|
50
|
+
|
|
51
|
+
## Transitions
|
|
52
|
+
|
|
53
|
+
There are two kinds of transition.
|
|
54
|
+
|
|
55
|
+
### Expand: `>`
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
old_state>next_state
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`expand` multiplies the current state by `base`.
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
next_state = old_state * base
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Split: `=`
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
old_state=pxq|r
|
|
71
|
+
old_state=p|r # when q == 1
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`split` divides the current state using `target`.
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
p = target
|
|
78
|
+
q = old_state // target
|
|
79
|
+
r = old_state % target
|
|
80
|
+
old_state = p * q + r
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Here, `p` and `q` describe the split, and `r` is the next state. When `q` is 1, `x1` is omitted. If the next state `r` was already visited, it is written as `(r)` and the body ends.
|
|
84
|
+
|
|
85
|
+
When the split has no remainder, it ends with `|!` instead of creating state `0`.
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
old_state=pxq|!
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
For the full DSL rules, see the [DSL specification](https://github.com/Imagination12357/xbtm/blob/main/docs/dsl-spec.md).
|
|
92
|
+
|
|
93
|
+
## Installation
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pip install xbtm
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Python usage
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from xbtm import Program, generate
|
|
103
|
+
|
|
104
|
+
program = generate(2, 5)
|
|
105
|
+
|
|
106
|
+
print(program.text)
|
|
107
|
+
print(program.get_trials())
|
|
108
|
+
|
|
109
|
+
same_program = Program.parse("X2T5:1>2>4>8=5|3>6=5|(1)")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Examples
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
X2T8:1>2>4>8!
|
|
116
|
+
X7T8:1>7>49=8x6|(1)
|
|
117
|
+
X1T1:1!
|
|
118
|
+
X4T2:1>4=2x2|!
|
|
119
|
+
```
|
xbtm-0.1.0/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
XbTm (X-base Target Mapping) is a tool and DSL for generating canonical, entropy-efficient mappings from an x-way random source to an m-way target choice.
|
|
2
|
+
|
|
3
|
+
`xbtm` is a DSL for deterministically exploring and visualizing ways to emulate a uniform random generator with `target` outcomes using one with `base` outcomes.
|
|
4
|
+
|
|
5
|
+
## DSL format
|
|
6
|
+
|
|
7
|
+
A complete program combines a header and a body with a colon.
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
X{base}T{target}:{body}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`base` and `target` are natural numbers. When `target` is at least 2, `base` must also be at least 2. When `target` is 1, `base` may be 1 because there is no outcome to choose between.
|
|
14
|
+
|
|
15
|
+
Every body starts at the ordinary state `1`.
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
X2T5:1>2>4>8=5|3>6=5|(1)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## States and termination
|
|
22
|
+
|
|
23
|
+
- `n`: An ordinary, newly visited state `n`, written as a natural number.
|
|
24
|
+
- `(n)`: A reference state that returns to the previously visited state `n`. A reference state terminates the body.
|
|
25
|
+
- `!`: A termination marker indicating that the current ordinary state exactly equals `target`. The implementation represents it as an operator token for convenience.
|
|
26
|
+
|
|
27
|
+
Thus, a body starts at an ordinary state, repeats transitions, and ends with either a reference state or `!`.
|
|
28
|
+
|
|
29
|
+
## Transitions
|
|
30
|
+
|
|
31
|
+
There are two kinds of transition.
|
|
32
|
+
|
|
33
|
+
### Expand: `>`
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
old_state>next_state
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`expand` multiplies the current state by `base`.
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
next_state = old_state * base
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Split: `=`
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
old_state=pxq|r
|
|
49
|
+
old_state=p|r # when q == 1
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`split` divides the current state using `target`.
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
p = target
|
|
56
|
+
q = old_state // target
|
|
57
|
+
r = old_state % target
|
|
58
|
+
old_state = p * q + r
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Here, `p` and `q` describe the split, and `r` is the next state. When `q` is 1, `x1` is omitted. If the next state `r` was already visited, it is written as `(r)` and the body ends.
|
|
62
|
+
|
|
63
|
+
When the split has no remainder, it ends with `|!` instead of creating state `0`.
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
old_state=pxq|!
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
For the full DSL rules, see the [DSL specification](https://github.com/Imagination12357/xbtm/blob/main/docs/dsl-spec.md).
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install xbtm
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Python usage
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from xbtm import Program, generate
|
|
81
|
+
|
|
82
|
+
program = generate(2, 5)
|
|
83
|
+
|
|
84
|
+
print(program.text)
|
|
85
|
+
print(program.get_trials())
|
|
86
|
+
|
|
87
|
+
same_program = Program.parse("X2T5:1>2>4>8=5|3>6=5|(1)")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Examples
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
X2T8:1>2>4>8!
|
|
94
|
+
X7T8:1>7>49=8x6|(1)
|
|
95
|
+
X1T1:1!
|
|
96
|
+
X4T2:1>4=2x2|!
|
|
97
|
+
```
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# XbTm DSL specification
|
|
2
|
+
|
|
3
|
+
This document is the normative specification for XbTm programs. Future parsing and validation must conform to this document; the current implementation may not yet support every rule below.
|
|
4
|
+
|
|
5
|
+
## 1. Lexical rules
|
|
6
|
+
|
|
7
|
+
Whitespace is not permitted. A **natural number** is a non-zero decimal integer:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
natural ::= [1-9][0-9]*
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The literal `x` is the DSL multiplication marker. In mathematical equations in this document, multiplication is written with `*`.
|
|
14
|
+
|
|
15
|
+
## 2. Program syntax
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
program ::= header ":" body
|
|
19
|
+
header ::= "X" natural "T" natural
|
|
20
|
+
body ::= "1" { ordinary_transition } terminal
|
|
21
|
+
|
|
22
|
+
ordinary_transition ::= ">" natural
|
|
23
|
+
| "=" natural [ "x" natural ] "|" natural
|
|
24
|
+
|
|
25
|
+
terminal ::= "!"
|
|
26
|
+
| ">" reference
|
|
27
|
+
| "=" natural [ "x" natural ] "|" reference
|
|
28
|
+
| "=" natural "x" natural "|" "!"
|
|
29
|
+
|
|
30
|
+
reference ::= "(" natural ")"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The grammar describes the character-level shape only. The semantic constraints in the next sections determine whether a syntactically valid program is well-formed.
|
|
34
|
+
|
|
35
|
+
## 3. Header constraints
|
|
36
|
+
|
|
37
|
+
Let `B` be the `base` value from `X{B}` and `T` be the `target` value from `T{T}`.
|
|
38
|
+
|
|
39
|
+
- `B` and `T` are natural numbers.
|
|
40
|
+
- If `T >= 2`, then `B >= 2`.
|
|
41
|
+
- `T = 1` permits `B >= 1`; it represents a target with no choice between outcomes.
|
|
42
|
+
|
|
43
|
+
## 4. State model
|
|
44
|
+
|
|
45
|
+
A normal state is a natural number. The body begins at normal state `1`.
|
|
46
|
+
|
|
47
|
+
While reading a program, maintain the current normal state `c` and the set `V` of previously visited normal states. Initially:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
c = 1
|
|
51
|
+
V = {1}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Every normal successor state must be absent from `V`; after it is accepted, add it to `V` and make it the new current state. A reference `(n)` is valid only when `n` is already in `V`. A reference is terminal and cannot be followed by another transition.
|
|
55
|
+
|
|
56
|
+
## 5. Transition semantics
|
|
57
|
+
|
|
58
|
+
The validator checks that each written operation is mathematically correct. It does not require the canonical or most efficient choice of operation.
|
|
59
|
+
|
|
60
|
+
### 5.1 Expand
|
|
61
|
+
|
|
62
|
+
An expand transition has the form:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
c>n
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
It is well-formed exactly when:
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
n = c * B
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`>` is permitted from every natural current state, including `c = T` and `c > T`. This deliberately permits non-canonical paths.
|
|
75
|
+
|
|
76
|
+
If `n` is new, it is written as `n` and the program continues. If `n` is already visited, it is written as `(n)` and the program terminates:
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
c>(n)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 5.2 Split with a non-zero remainder
|
|
83
|
+
|
|
84
|
+
A non-terminal split has one of these forms:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
c=p|r
|
|
88
|
+
c=pxq|r
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
It is well-formed exactly when:
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
c > T
|
|
95
|
+
p = T
|
|
96
|
+
q = c // T
|
|
97
|
+
r = c % T
|
|
98
|
+
c = p * q + r
|
|
99
|
+
1 <= r < T
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The `xq` portion is omitted if and only if `q = 1`. It is required when `q > 1`.
|
|
103
|
+
|
|
104
|
+
The next state is `r`. If `r` is new, it is written as `r` and the program continues. If `r` is already visited, it is written as `(r)` and the program terminates:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
c=p|(r)
|
|
108
|
+
c=pxq|(r)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Split is not allowed when `c <= T`. In particular, `c = T` must not be written as the meaningless expression `T = T * 1 + 0`.
|
|
112
|
+
|
|
113
|
+
### 5.3 Exact split termination
|
|
114
|
+
|
|
115
|
+
If a split has no remainder, it is an immediate successful termination:
|
|
116
|
+
|
|
117
|
+
```text
|
|
118
|
+
c=pxq|!
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
It is well-formed exactly when:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
c > T
|
|
125
|
+
p = T
|
|
126
|
+
q = c // T
|
|
127
|
+
q >= 2
|
|
128
|
+
c % T = 0
|
|
129
|
+
c = p * q
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The `|!` suffix represents that no remainder or retry state remains; it never creates state `0`. The `c` equally likely outcomes can be partitioned into `q` complete groups of `T` outcomes.
|
|
133
|
+
|
|
134
|
+
For example:
|
|
135
|
+
|
|
136
|
+
```text
|
|
137
|
+
X6T3:1>6=3x2|!
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## 6. Successful state termination
|
|
141
|
+
|
|
142
|
+
The terminal marker `!` may immediately follow a normal state:
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
c!
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
This form is well-formed exactly when `c = T`.
|
|
149
|
+
|
|
150
|
+
It is not mandatory to terminate immediately when `c = T`: an expand transition may follow it to express a non-canonical path. However, a program that uses the standalone `!` marker must satisfy `c = T` at that point.
|
|
151
|
+
|
|
152
|
+
## 7. Validation scope
|
|
153
|
+
|
|
154
|
+
A validator must reject, at minimum:
|
|
155
|
+
|
|
156
|
+
- malformed headers, tokens, or trailing text;
|
|
157
|
+
- zero or negative state values;
|
|
158
|
+
- bodies that do not start at `1`;
|
|
159
|
+
- repeated normal states;
|
|
160
|
+
- references to states not previously visited;
|
|
161
|
+
- any text after a reference or terminal `!`;
|
|
162
|
+
- incorrect expand or split arithmetic;
|
|
163
|
+
- an omitted `xq` when `q > 1`, or a written `x1` when `q = 1`;
|
|
164
|
+
- a non-exact split with `r = 0`;
|
|
165
|
+
- a split from `c <= T`;
|
|
166
|
+
- standalone `!` after a state other than `T`.
|
|
167
|
+
|
|
168
|
+
Selecting the canonical path—expand when `c < T`, terminate when `c = T`, and split when `c > T`—is an optimization policy, not a well-formedness requirement. It must not be enforced by the general validator.
|