relibmss 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.
@@ -0,0 +1,44 @@
1
+ # ベースイメージとして最新のUbuntuを使用
2
+ FROM ubuntu:22.04
3
+
4
+ # 環境変数の設定
5
+ ENV DEBIAN_FRONTEND=noninteractive
6
+
7
+ # 必要なパッケージのインストール
8
+ RUN apt-get update && apt-get install -y \
9
+ build-essential \
10
+ curl \
11
+ git \
12
+ libssl-dev \
13
+ pkg-config \
14
+ python3 \
15
+ python3-pip \
16
+ python3-venv \
17
+ && rm -rf /var/lib/apt/lists/*
18
+
19
+ # ユーザー作成
20
+ RUN useradd -m vscode
21
+
22
+ # 作業ディレクトリの設定
23
+ WORKDIR /home/vscode
24
+
25
+ # vscode ユーザーに切り替え
26
+ USER vscode
27
+
28
+ # Rust のインストール(vscode ユーザーとして)
29
+ RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
30
+
31
+ # 環境変数 PATH の設定(vscode ユーザー用)
32
+ ENV PATH="/home/vscode/.cargo/bin:${PATH}"
33
+
34
+ # maturin のインストール(vscode ユーザーとして)
35
+ RUN pip3 install --user --upgrade pip
36
+ RUN pip3 install --user maturin
37
+
38
+ # .local/bin を PATH に追加
39
+ ENV PATH="/home/vscode/.local/bin:${PATH}"
40
+
41
+ # 作業ディレクトリをホームに設定
42
+ WORKDIR /home/vscode
43
+
44
+ CMD ["/bin/bash"]
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "Python-Rust Dev Container",
3
+ "build": {
4
+ "dockerfile": "Dockerfile",
5
+ "context": ".."
6
+ },
7
+ "customizations": {
8
+ "vscode": {
9
+ "settings": {
10
+ "python.pythonPath": "/home/vscode/.venv/bin/python",
11
+ "terminal.integrated.shell.linux": "/bin/bash"
12
+ },
13
+ "extensions": [
14
+ "ms-python.python",
15
+ "rust-lang.rust-analyzer"
16
+ ]
17
+ }
18
+ },
19
+ "postCreateCommand": "./setup.sh",
20
+ "remoteUser": "vscode"
21
+ }
@@ -0,0 +1,30 @@
1
+ name: Build and Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v3
15
+
16
+ - name: Install Rust
17
+ uses: actions-rs/toolchain@v1
18
+ with:
19
+ toolchain: stable
20
+
21
+ - name: Install maturin
22
+ run: pip install maturin==1.7.8
23
+
24
+ - name: Build Python package
25
+ run: maturin build --release
26
+
27
+ - name: Build and publish
28
+ env:
29
+ MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
30
+ run: maturin publish --non-interactive
@@ -0,0 +1,22 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ *.pyd
6
+ *.egg-info/
7
+ dist/
8
+ build/
9
+ .mypy_cache/
10
+ .pytest_cache/
11
+
12
+ # Rust
13
+ target/
14
+ *.rs.bk
15
+ Cargo.lock
16
+
17
+ # Dev Container
18
+ .devcontainer/.local/
19
+
20
+ # venv
21
+ .venv/
22
+
@@ -0,0 +1,314 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.4.0"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
10
+
11
+ [[package]]
12
+ name = "bitflags"
13
+ version = "2.6.0"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
16
+
17
+ [[package]]
18
+ name = "cfg-if"
19
+ version = "1.0.0"
20
+ source = "registry+https://github.com/rust-lang/crates.io-index"
21
+ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
22
+
23
+ [[package]]
24
+ name = "dd"
25
+ version = "0.2.0"
26
+ source = "git+https://github.com/okamumu/rust-dd.git#78165bb7ef8720c5bd7a8d53de8480150a10724f"
27
+ dependencies = [
28
+ "num-traits",
29
+ "wyhash",
30
+ ]
31
+
32
+ [[package]]
33
+ name = "indoc"
34
+ version = "1.0.9"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306"
37
+
38
+ [[package]]
39
+ name = "libc"
40
+ version = "0.2.167"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
43
+
44
+ [[package]]
45
+ name = "lock_api"
46
+ version = "0.4.12"
47
+ source = "registry+https://github.com/rust-lang/crates.io-index"
48
+ checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
49
+ dependencies = [
50
+ "autocfg",
51
+ "scopeguard",
52
+ ]
53
+
54
+ [[package]]
55
+ name = "memoffset"
56
+ version = "0.8.0"
57
+ source = "registry+https://github.com/rust-lang/crates.io-index"
58
+ checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
59
+ dependencies = [
60
+ "autocfg",
61
+ ]
62
+
63
+ [[package]]
64
+ name = "num-traits"
65
+ version = "0.2.19"
66
+ source = "registry+https://github.com/rust-lang/crates.io-index"
67
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
68
+ dependencies = [
69
+ "autocfg",
70
+ ]
71
+
72
+ [[package]]
73
+ name = "once_cell"
74
+ version = "1.20.2"
75
+ source = "registry+https://github.com/rust-lang/crates.io-index"
76
+ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
77
+
78
+ [[package]]
79
+ name = "parking_lot"
80
+ version = "0.12.3"
81
+ source = "registry+https://github.com/rust-lang/crates.io-index"
82
+ checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
83
+ dependencies = [
84
+ "lock_api",
85
+ "parking_lot_core",
86
+ ]
87
+
88
+ [[package]]
89
+ name = "parking_lot_core"
90
+ version = "0.9.10"
91
+ source = "registry+https://github.com/rust-lang/crates.io-index"
92
+ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
93
+ dependencies = [
94
+ "cfg-if",
95
+ "libc",
96
+ "redox_syscall",
97
+ "smallvec",
98
+ "windows-targets",
99
+ ]
100
+
101
+ [[package]]
102
+ name = "proc-macro2"
103
+ version = "1.0.92"
104
+ source = "registry+https://github.com/rust-lang/crates.io-index"
105
+ checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
106
+ dependencies = [
107
+ "unicode-ident",
108
+ ]
109
+
110
+ [[package]]
111
+ name = "pyo3"
112
+ version = "0.18.3"
113
+ source = "registry+https://github.com/rust-lang/crates.io-index"
114
+ checksum = "e3b1ac5b3731ba34fdaa9785f8d74d17448cd18f30cf19e0c7e7b1fdb5272109"
115
+ dependencies = [
116
+ "cfg-if",
117
+ "indoc",
118
+ "libc",
119
+ "memoffset",
120
+ "parking_lot",
121
+ "pyo3-build-config",
122
+ "pyo3-ffi",
123
+ "pyo3-macros",
124
+ "unindent",
125
+ ]
126
+
127
+ [[package]]
128
+ name = "pyo3-build-config"
129
+ version = "0.18.3"
130
+ source = "registry+https://github.com/rust-lang/crates.io-index"
131
+ checksum = "9cb946f5ac61bb61a5014924910d936ebd2b23b705f7a4a3c40b05c720b079a3"
132
+ dependencies = [
133
+ "once_cell",
134
+ "target-lexicon",
135
+ ]
136
+
137
+ [[package]]
138
+ name = "pyo3-ffi"
139
+ version = "0.18.3"
140
+ source = "registry+https://github.com/rust-lang/crates.io-index"
141
+ checksum = "fd4d7c5337821916ea2a1d21d1092e8443cf34879e53a0ac653fbb98f44ff65c"
142
+ dependencies = [
143
+ "libc",
144
+ "pyo3-build-config",
145
+ ]
146
+
147
+ [[package]]
148
+ name = "pyo3-macros"
149
+ version = "0.18.3"
150
+ source = "registry+https://github.com/rust-lang/crates.io-index"
151
+ checksum = "a9d39c55dab3fc5a4b25bbd1ac10a2da452c4aca13bb450f22818a002e29648d"
152
+ dependencies = [
153
+ "proc-macro2",
154
+ "pyo3-macros-backend",
155
+ "quote",
156
+ "syn",
157
+ ]
158
+
159
+ [[package]]
160
+ name = "pyo3-macros-backend"
161
+ version = "0.18.3"
162
+ source = "registry+https://github.com/rust-lang/crates.io-index"
163
+ checksum = "97daff08a4c48320587b5224cc98d609e3c27b6d437315bd40b605c98eeb5918"
164
+ dependencies = [
165
+ "proc-macro2",
166
+ "quote",
167
+ "syn",
168
+ ]
169
+
170
+ [[package]]
171
+ name = "quote"
172
+ version = "1.0.37"
173
+ source = "registry+https://github.com/rust-lang/crates.io-index"
174
+ checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
175
+ dependencies = [
176
+ "proc-macro2",
177
+ ]
178
+
179
+ [[package]]
180
+ name = "rand_core"
181
+ version = "0.6.4"
182
+ source = "registry+https://github.com/rust-lang/crates.io-index"
183
+ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
184
+
185
+ [[package]]
186
+ name = "redox_syscall"
187
+ version = "0.5.7"
188
+ source = "registry+https://github.com/rust-lang/crates.io-index"
189
+ checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
190
+ dependencies = [
191
+ "bitflags",
192
+ ]
193
+
194
+ [[package]]
195
+ name = "relibmss"
196
+ version = "0.1.0"
197
+ dependencies = [
198
+ "dd",
199
+ "pyo3",
200
+ ]
201
+
202
+ [[package]]
203
+ name = "scopeguard"
204
+ version = "1.2.0"
205
+ source = "registry+https://github.com/rust-lang/crates.io-index"
206
+ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
207
+
208
+ [[package]]
209
+ name = "smallvec"
210
+ version = "1.13.2"
211
+ source = "registry+https://github.com/rust-lang/crates.io-index"
212
+ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
213
+
214
+ [[package]]
215
+ name = "syn"
216
+ version = "1.0.109"
217
+ source = "registry+https://github.com/rust-lang/crates.io-index"
218
+ checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
219
+ dependencies = [
220
+ "proc-macro2",
221
+ "quote",
222
+ "unicode-ident",
223
+ ]
224
+
225
+ [[package]]
226
+ name = "target-lexicon"
227
+ version = "0.12.16"
228
+ source = "registry+https://github.com/rust-lang/crates.io-index"
229
+ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
230
+
231
+ [[package]]
232
+ name = "unicode-ident"
233
+ version = "1.0.14"
234
+ source = "registry+https://github.com/rust-lang/crates.io-index"
235
+ checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
236
+
237
+ [[package]]
238
+ name = "unindent"
239
+ version = "0.1.11"
240
+ source = "registry+https://github.com/rust-lang/crates.io-index"
241
+ checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c"
242
+
243
+ [[package]]
244
+ name = "windows-targets"
245
+ version = "0.52.6"
246
+ source = "registry+https://github.com/rust-lang/crates.io-index"
247
+ checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
248
+ dependencies = [
249
+ "windows_aarch64_gnullvm",
250
+ "windows_aarch64_msvc",
251
+ "windows_i686_gnu",
252
+ "windows_i686_gnullvm",
253
+ "windows_i686_msvc",
254
+ "windows_x86_64_gnu",
255
+ "windows_x86_64_gnullvm",
256
+ "windows_x86_64_msvc",
257
+ ]
258
+
259
+ [[package]]
260
+ name = "windows_aarch64_gnullvm"
261
+ version = "0.52.6"
262
+ source = "registry+https://github.com/rust-lang/crates.io-index"
263
+ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
264
+
265
+ [[package]]
266
+ name = "windows_aarch64_msvc"
267
+ version = "0.52.6"
268
+ source = "registry+https://github.com/rust-lang/crates.io-index"
269
+ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
270
+
271
+ [[package]]
272
+ name = "windows_i686_gnu"
273
+ version = "0.52.6"
274
+ source = "registry+https://github.com/rust-lang/crates.io-index"
275
+ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
276
+
277
+ [[package]]
278
+ name = "windows_i686_gnullvm"
279
+ version = "0.52.6"
280
+ source = "registry+https://github.com/rust-lang/crates.io-index"
281
+ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
282
+
283
+ [[package]]
284
+ name = "windows_i686_msvc"
285
+ version = "0.52.6"
286
+ source = "registry+https://github.com/rust-lang/crates.io-index"
287
+ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
288
+
289
+ [[package]]
290
+ name = "windows_x86_64_gnu"
291
+ version = "0.52.6"
292
+ source = "registry+https://github.com/rust-lang/crates.io-index"
293
+ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
294
+
295
+ [[package]]
296
+ name = "windows_x86_64_gnullvm"
297
+ version = "0.52.6"
298
+ source = "registry+https://github.com/rust-lang/crates.io-index"
299
+ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
300
+
301
+ [[package]]
302
+ name = "windows_x86_64_msvc"
303
+ version = "0.52.6"
304
+ source = "registry+https://github.com/rust-lang/crates.io-index"
305
+ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
306
+
307
+ [[package]]
308
+ name = "wyhash"
309
+ version = "0.5.0"
310
+ source = "registry+https://github.com/rust-lang/crates.io-index"
311
+ checksum = "baf6e163c25e3fac820b4b453185ea2dea3b6a3e0a721d4d23d75bd33734c295"
312
+ dependencies = [
313
+ "rand_core",
314
+ ]
@@ -0,0 +1,17 @@
1
+ [package]
2
+ name = "relibmss"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ license = "MIT"
6
+ repository = "https://github.com/okamumu/relibmss"
7
+ homepage = "https://github.com/okamumu/relibmss"
8
+ documentation = "https://github.com/okamumu/relibmss"
9
+
10
+ [lib]
11
+ name = "relibmss"
12
+ crate-type = ["cdylib"]
13
+
14
+ [dependencies]
15
+ pyo3 = { version = "0.18.3", features = ["extension-module"] }
16
+ dd = { version = "0.2.0", git = "https://github.com/okamumu/rust-dd.git" }
17
+
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.4
2
+ Name: relibmss
3
+ Version: 0.1.0
4
+ Summary: A Python package for binary/multi state systems
5
+ Home-Page: https://github.com/okamumu/relibmss
6
+ Author-email: Hiroyuki Okamura <okamu@hiroshima-u.ac.jp>
7
+ License: MIT
8
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
9
+ Project-URL: Source Code, https://github.com/okamumu/relibmss
10
+
11
+ # relibmss
12
+
13
+ A Python package for binary/multi state systems with BDD/MDD.
14
+
15
+
@@ -0,0 +1,4 @@
1
+ # relibmss
2
+
3
+ A Python package for binary/multi state systems with BDD/MDD.
4
+
@@ -0,0 +1,3 @@
1
+ maturin
2
+ pytest>=7.0.0
3
+
@@ -0,0 +1,14 @@
1
+ [build-system]
2
+ requires = ["maturin>=1.7,<2.0"]
3
+ build-backend = "maturin"
4
+
5
+ [project]
6
+ name = "relibmss"
7
+ version = "0.1.0"
8
+ authors = [{ name = "Hiroyuki Okamura", email = "okamu@hiroshima-u.ac.jp" }]
9
+ description = "A Python package for binary/multi state systems"
10
+ readme = "README.md"
11
+ license = { text = "MIT" }
12
+
13
+ [tool.maturin]
14
+ bindings = "pyo3"
@@ -0,0 +1,15 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # 仮想環境の作成
5
+ python3 -m venv .venv
6
+
7
+ # 仮想環境の有効化
8
+ source .venv/bin/activate
9
+
10
+ # pip のアップグレード
11
+ pip install --upgrade pip
12
+
13
+ # 依存関係のインストール
14
+ pip install -r dev-requirements.txt
15
+
@@ -0,0 +1,235 @@
1
+ //
2
+
3
+ use dd::bdd;
4
+ use pyo3::exceptions::PyValueError;
5
+ use std::io::BufWriter;
6
+ use dd::dot::Dot;
7
+ use dd::count::*;
8
+
9
+ use std::rc::Weak;
10
+ use std::rc::Rc;
11
+ use std::cell::RefCell;
12
+ use std::collections::HashMap;
13
+
14
+ use pyo3::prelude::*;
15
+
16
+ use crate::ft;
17
+
18
+ #[pyclass(unsendable)]
19
+ pub struct BddMgr {
20
+ pub bdd: Rc<RefCell<bdd::Bdd>>,
21
+ pub vars: HashMap<String, bdd::BddNode>,
22
+ }
23
+
24
+ #[pymethods]
25
+ impl BddMgr {
26
+ // constructor
27
+ #[new]
28
+ pub fn new() -> Self {
29
+ BddMgr {
30
+ bdd: Rc::new(RefCell::new(bdd::Bdd::new())),
31
+ vars: HashMap::new(),
32
+ }
33
+ }
34
+
35
+ // size
36
+ pub fn size(&self) -> (usize, usize, usize) {
37
+ self.bdd.borrow().size()
38
+ }
39
+
40
+ // zero
41
+ pub fn zero(&self) -> BddNode {
42
+ BddNode::new(self.bdd.clone(), self.bdd.borrow().zero())
43
+
44
+ }
45
+
46
+ // one
47
+ pub fn one(&self) -> BddNode {
48
+ BddNode::new(self.bdd.clone(), self.bdd.borrow().one())
49
+ }
50
+
51
+ // var
52
+ pub fn var(&mut self, var: &str) -> BddNode {
53
+ let level = self.vars.len();
54
+ let mut bdd = self.bdd.borrow_mut();
55
+ let h = bdd.header(level, var);
56
+ let x0 = bdd.zero();
57
+ let x1 = bdd.one();
58
+ let node = bdd.create_node(&h, &x0, &x1);
59
+ self.vars.insert(var.to_string(), node.clone());
60
+ BddNode::new(self.bdd.clone(), node)
61
+ }
62
+
63
+ // vars
64
+ pub fn vars(&mut self, vars: Vec<&str>) -> Vec<BddNode> {
65
+ let mut bdd = self.bdd.borrow_mut();
66
+ let mut nodes = Vec::new();
67
+ for (level, v) in vars.iter().enumerate() {
68
+ let h = bdd.header(level, v);
69
+ let x0 = bdd.zero();
70
+ let x1 = bdd.one();
71
+ let b = vec![bdd.zero(), bdd.one()];
72
+ let node = bdd.create_node(&h, &x0, &x1);
73
+ self.vars.insert(v.to_string(), node.clone());
74
+ let x = BddNode::new(self.bdd.clone(), node);
75
+ nodes.push(x);
76
+ }
77
+ nodes
78
+ }
79
+
80
+ pub fn rpn(&mut self, expr: &str) -> PyResult<BddNode> {
81
+ let mut stack = Vec::new();
82
+ let mut bdd = self.bdd.borrow_mut();
83
+ for token in expr.split_whitespace() {
84
+ match token {
85
+ "0" => stack.push(bdd.zero()),
86
+ "1" => stack.push(bdd.one()),
87
+ "&" => {
88
+ let right = stack.pop().unwrap();
89
+ let left = stack.pop().unwrap();
90
+ stack.push(bdd.and(&left, &right));
91
+ }
92
+ "|" => {
93
+ let right = stack.pop().unwrap();
94
+ let left = stack.pop().unwrap();
95
+ stack.push(bdd.or(&left, &right));
96
+ }
97
+ "^" => {
98
+ let right = stack.pop().unwrap();
99
+ let left = stack.pop().unwrap();
100
+ stack.push(bdd.xor(&left, &right));
101
+ }
102
+ "~" => {
103
+ let node = stack.pop().unwrap();
104
+ stack.push(bdd.not(&node));
105
+ }
106
+ "?" => {
107
+ let else_ = stack.pop().unwrap();
108
+ let then = stack.pop().unwrap();
109
+ let cond = stack.pop().unwrap();
110
+ stack.push(bdd.ite(&cond, &then, &else_));
111
+ }
112
+ _ => {
113
+ if let Some(node) = self.vars.get(token) {
114
+ stack.push(node.clone());
115
+ } else {
116
+ return Err(PyValueError::new_err("unknown token"));
117
+ }
118
+ }
119
+ }
120
+ }
121
+ if stack.len() != 1 {
122
+ return Err(PyValueError::new_err("Invalid expression"));
123
+ }
124
+ Ok(BddNode::new(self.bdd.clone(), stack.pop().unwrap()))
125
+ }
126
+
127
+ pub fn and(&self, nodes: Vec<BddNode>) -> BddNode {
128
+ let mut bdd = self.bdd.borrow_mut();
129
+ let bnodes = nodes.iter().map(|n| n.node()).collect::<Vec<_>>();
130
+ let result = ft::_and(&mut bdd, bnodes);
131
+ BddNode::new(self.bdd.clone(), result)
132
+ }
133
+
134
+ pub fn or(&self, nodes: Vec<BddNode>) -> BddNode {
135
+ let mut bdd = self.bdd.borrow_mut();
136
+ let bnodes = nodes.iter().map(|n| n.node()).collect::<Vec<_>>();
137
+ let result = ft::_or(&mut bdd, bnodes);
138
+ BddNode::new(self.bdd.clone(), result)
139
+ }
140
+
141
+ pub fn kofn(&self, k: usize, nodes: Vec<BddNode>) -> BddNode {
142
+ let mut bdd = self.bdd.borrow_mut();
143
+ let bnodes = nodes.iter().map(|n| n.node()).collect::<Vec<_>>();
144
+ let result = ft::kofn(&mut bdd, k, bnodes);
145
+ BddNode::new(self.bdd.clone(), result)
146
+ }
147
+ }
148
+
149
+ #[pyclass(unsendable)]
150
+ #[derive(Clone)]
151
+ pub struct BddNode {
152
+ bdd: Weak<RefCell<bdd::Bdd>>,
153
+ node: bdd::BddNode,
154
+ }
155
+
156
+ impl BddNode {
157
+ pub fn new(bdd: Rc<RefCell<bdd::Bdd>>, node: bdd::BddNode) -> Self {
158
+ BddNode {
159
+ bdd: Rc::downgrade(&bdd),
160
+ node: node,
161
+ }
162
+ }
163
+
164
+ pub fn node(&self) -> bdd::BddNode {
165
+ self.node.clone()
166
+ }
167
+ }
168
+
169
+ #[pymethods]
170
+ impl BddNode {
171
+ pub fn dot(&self) -> String {
172
+ let mut buf = vec![];
173
+ {
174
+ let mut io = BufWriter::new(&mut buf);
175
+ self.node.dot(&mut io);
176
+ }
177
+ std::str::from_utf8(&buf).unwrap().to_string()
178
+ }
179
+
180
+ fn __and__(&self, other: &BddNode) -> BddNode {
181
+ let bdd = self.bdd.upgrade().unwrap();
182
+ BddNode::new(bdd.clone(), bdd.clone().borrow_mut().and(&self.node, &other.node))
183
+ }
184
+
185
+ fn __or__(&self, other: &BddNode) -> BddNode {
186
+ let bdd = self.bdd.upgrade().unwrap();
187
+ BddNode::new(bdd.clone(), bdd.clone().borrow_mut().or(&self.node, &other.node))
188
+ }
189
+
190
+ fn __xor__(&self, other: &BddNode) -> BddNode {
191
+ let bdd = self.bdd.upgrade().unwrap();
192
+ BddNode::new(bdd.clone(), bdd.clone().borrow_mut().xor(&self.node, &other.node))
193
+ }
194
+
195
+ fn __invert__(&self) -> BddNode {
196
+ let bdd = self.bdd.upgrade().unwrap();
197
+ BddNode::new(bdd.clone(), bdd.clone().borrow_mut().not(&self.node))
198
+ }
199
+
200
+ pub fn prob(&self, pv: HashMap<String, f64>) -> f64 {
201
+ let bdd = self.bdd.upgrade().unwrap();
202
+ ft::prob(&mut bdd.clone().borrow_mut(), &self.node, pv)
203
+ }
204
+
205
+ pub fn mcs(&self) -> BddNode {
206
+ let bdd = self.bdd.upgrade().unwrap();
207
+ BddNode::new(bdd.clone(), ft::minsol(&mut bdd.clone().borrow_mut(), &self.node))
208
+ }
209
+
210
+ pub fn extract(&self) -> Vec<Vec<String>> {
211
+ let bdd = self.bdd.upgrade().unwrap();
212
+ ft::extract(&mut bdd.clone().borrow_mut(), &self.node)
213
+ }
214
+
215
+ pub fn count(&self) -> (usize, u64) {
216
+ self.node.count()
217
+ }
218
+ }
219
+
220
+ #[pyfunction]
221
+ pub fn ifelse(cond: &BddNode, then: &BddNode, else_: &BddNode) -> BddNode {
222
+ let bdd = cond.bdd.upgrade().unwrap();
223
+ BddNode::new(bdd.clone(), bdd.clone().borrow_mut().ite(&cond.node, &then.node, &else_.node))
224
+ }
225
+
226
+ #[pyfunction]
227
+ pub fn kofn(k: usize, nodes: Vec<BddNode>) -> PyResult<BddNode> {
228
+ if nodes.len() < k {
229
+ return Err(PyValueError::new_err("Invalid expression"));
230
+ }
231
+ let bdd = nodes[0].bdd.upgrade().unwrap();
232
+ let nodes = nodes.iter().map(|n| n.node()).collect::<Vec<_>>();
233
+ Ok(BddNode::new(bdd.clone(), ft::kofn(&mut bdd.clone().borrow_mut(), k, nodes)))
234
+ }
235
+
@@ -0,0 +1,109 @@
1
+ // mod ft
2
+
3
+ use std::collections::HashMap;
4
+
5
+ use dd::bdd::*;
6
+ use dd::common::NodeId;
7
+ use dd::nodes::NonTerminal;
8
+
9
+ pub fn kofn(bdd: &mut Bdd, k: usize, nodes: Vec<BddNode>) -> BddNode {
10
+ match k {
11
+ 1 => _or(bdd, nodes),
12
+ _ if nodes.len() == k => _and(bdd, nodes),
13
+ _ => {
14
+ let tmp1 = kofn(bdd, k - 1, nodes[1..].to_vec());
15
+ let tmp2 = kofn(bdd, k, nodes[1..].to_vec());
16
+ bdd.ite(&nodes[0], &tmp1, &tmp2)
17
+ }
18
+ }
19
+ }
20
+
21
+ pub fn _and(bdd: &mut Bdd, nodes: Vec<BddNode>) -> BddNode {
22
+ let mut res = bdd.one();
23
+ for node in nodes.iter() {
24
+ res = bdd.and(&res, &node);
25
+ }
26
+ res
27
+ }
28
+
29
+ pub fn _or(bdd: &mut Bdd, nodes: Vec<BddNode>) -> BddNode {
30
+ let mut res = bdd.zero();
31
+ for node in nodes.iter() {
32
+ res = bdd.or(&res, &node);
33
+ }
34
+ res
35
+ }
36
+
37
+ // prob
38
+ pub fn prob(bdd: &mut Bdd, node: &BddNode, pv: HashMap<String,f64>) -> f64 {
39
+ let cache = &mut HashMap::new();
40
+ _prob(bdd, &node, &pv, cache)
41
+ }
42
+
43
+ fn _prob(bdd: &mut Bdd, node: &BddNode, pv: &HashMap<String,f64>, cache: &mut HashMap<NodeId,f64>) -> f64 {
44
+ let key = node.id();
45
+ match cache.get(&key) {
46
+ Some(x) => x.clone(),
47
+ None => {
48
+ let result = match node {
49
+ BddNode::Zero => 1.0,
50
+ BddNode::One => 0.0,
51
+ BddNode::NonTerminal(fnode) => {
52
+ let x = fnode.header().label();
53
+ let fp = pv.get(x).unwrap_or(&0.0).clone();
54
+ let low = _prob(bdd, &fnode[0], pv, cache);
55
+ let high = _prob(bdd, &fnode[1], pv, cache);
56
+ fp * low + (1.0 - fp) * high
57
+ },
58
+ };
59
+ cache.insert(key, result);
60
+ result
61
+ }
62
+ }
63
+ }
64
+
65
+ pub fn minsol(bdd: &mut Bdd, node: &BddNode) -> BddNode {
66
+ let cache = &mut HashMap::new();
67
+ _minsol(bdd, &node, cache)
68
+ }
69
+
70
+ fn _minsol(dd: &mut Bdd, node: &BddNode, cache: &mut HashMap<NodeId,BddNode>) -> BddNode {
71
+ let key = node.id();
72
+ match cache.get(&key) {
73
+ Some(x) => x.clone(),
74
+ None => {
75
+ let result = match node {
76
+ BddNode::Zero => dd.zero(),
77
+ BddNode::One => dd.one(),
78
+ BddNode::NonTerminal(fnode) => {
79
+ let tmp = _minsol(dd, &fnode[1], cache);
80
+ let high = dd.setdiff(&tmp, &fnode[0]);
81
+ let low = _minsol(dd, &fnode[0], cache);
82
+ dd.create_node(fnode.header(), &low, &high)
83
+ },
84
+ };
85
+ cache.insert(key, result.clone());
86
+ result
87
+ }
88
+ }
89
+ }
90
+
91
+ pub fn extract(bdd: &mut Bdd, node: &BddNode) -> Vec<Vec<String>> {
92
+ let mut pathset = Vec::new();
93
+ _extract(node, &mut Vec::new(), &mut pathset);
94
+ pathset
95
+ }
96
+
97
+ fn _extract(node: &BddNode, path: &mut Vec<String>, pathset: &mut Vec<Vec<String>>) {
98
+ match node {
99
+ BddNode::Zero => (),
100
+ BddNode::One => pathset.push(path.clone()),
101
+ BddNode::NonTerminal(fnode) => {
102
+ let x = fnode.header().label();
103
+ path.push(x.to_string());
104
+ _extract(&fnode[1], path, pathset);
105
+ path.pop();
106
+ _extract(&fnode[0], path, pathset);
107
+ },
108
+ }
109
+ }
@@ -0,0 +1,277 @@
1
+ //
2
+
3
+
4
+ use std::borrow::BorrowMut;
5
+ use std::collections::HashMap;
6
+ use std::rc::Weak;
7
+ use std::rc::Rc;
8
+ use std::cell::RefCell;
9
+
10
+ use pyo3::prelude::*;
11
+
12
+ use crate::bdd as pybdd;
13
+
14
+ pub enum FTNode {
15
+ Basic {
16
+ id: usize,
17
+ name: String,
18
+ },
19
+ Repeat {
20
+ id: usize,
21
+ name: String,
22
+ },
23
+ And {
24
+ id: usize,
25
+ args: Vec<FtNode>,
26
+ },
27
+ Or {
28
+ id: usize,
29
+ args: Vec<FtNode>,
30
+ },
31
+ KofN {
32
+ id: usize,
33
+ k: usize,
34
+ args: Vec<FtNode>,
35
+ },
36
+ }
37
+
38
+ pub struct Var {
39
+ pub node: Vec<String>,
40
+ pub bddnode: pybdd::BddNode,
41
+ }
42
+
43
+ struct FTMgr {
44
+ pub id: RefCell<usize>,
45
+ pub events: RefCell<HashMap<String,Var>>,
46
+ pub bddnode: RefCell<HashMap<usize,pybdd::BddNode>>,
47
+ }
48
+
49
+ impl FTMgr {
50
+ pub fn new() -> FTMgr {
51
+ FTMgr {
52
+ id: RefCell::new(0),
53
+ events: RefCell::new(HashMap::new()),
54
+ bddnode: RefCell::new(HashMap::new()),
55
+ }
56
+ }
57
+
58
+ pub fn id(&self) -> usize {
59
+ *self.id.borrow()
60
+ }
61
+
62
+ fn basic(mgr: &Rc<RefCell<Self>>, name: &str) -> FtNode {
63
+ let mgr_borrow = mgr.borrow();
64
+ let node = FTNode::Basic { id: mgr_borrow.id(), name: name.to_string() };
65
+ *mgr_borrow.id.borrow_mut() += 1;
66
+ FtNode::new(mgr.clone(), Rc::new(node))
67
+ }
68
+
69
+ fn repeat(mgr: &Rc<RefCell<Self>>, name: &str) -> FtNode {
70
+ let mgr_borrow = mgr.borrow();
71
+ let node = FTNode::Repeat { id: mgr_borrow.id(), name: name.to_string() };
72
+ *mgr_borrow.id.borrow_mut() += 1;
73
+ FtNode::new(mgr.clone(), Rc::new(node))
74
+ }
75
+
76
+ fn and(mgr: &Rc<RefCell<Self>>, args: Vec<FtNode>) -> FtNode {
77
+ let mgr_borrow = mgr.borrow();
78
+ let node = FTNode::And { id: mgr_borrow.id(), args };
79
+ *mgr_borrow.id.borrow_mut() += 1;
80
+ FtNode::new(mgr.clone(), Rc::new(node))
81
+ }
82
+
83
+ fn or(mgr: &Rc<RefCell<Self>>, args: Vec<FtNode>) -> FtNode {
84
+ let mgr_borrow = mgr.borrow();
85
+ let node = FTNode::Or { id: mgr_borrow.id(), args };
86
+ *mgr_borrow.id.borrow_mut() += 1;
87
+ FtNode::new(mgr.clone(), Rc::new(node))
88
+ }
89
+
90
+ fn kofn(mgr: &Rc<RefCell<Self>>, k: usize, args: Vec<FtNode>) -> FtNode {
91
+ let mgr_borrow = mgr.borrow();
92
+ let node = FTNode::KofN { id: mgr_borrow.id(), k, args };
93
+ *mgr_borrow.id.borrow_mut() += 1;
94
+ FtNode::new(mgr.clone(), Rc::new(node))
95
+ }
96
+
97
+ fn create(mgr: &Rc<RefCell<Self>>, bddmgr: &mut pybdd::BddMgr, top: FtNode) -> pybdd::BddNode {
98
+ let ftmgr = mgr.borrow();
99
+ let node = top.node();
100
+ match node.as_ref() {
101
+ FTNode::Basic { id, name } => {
102
+ if let Some(v) = ftmgr.events.borrow_mut().get_mut(name) {
103
+ let u = v.node.len();
104
+ let name_ = format!("{}_{}", name, u);
105
+ let x = bddmgr.var(&name_);
106
+ v.node.push(name_);
107
+ v.bddnode = x.clone();
108
+ return x
109
+ }
110
+ let name_ = format!("{}_0", name);
111
+ let x = bddmgr.var(&name_);
112
+ let v = Var { node: vec![name_], bddnode: x.clone() };
113
+ {
114
+ let mut events = ftmgr.events.borrow_mut();
115
+ events.insert(name.clone(), v);
116
+ }
117
+ x
118
+ }
119
+ FTNode::Repeat { id, name } => {
120
+ if let Some(v) = ftmgr.events.borrow().get(name) {
121
+ return v.bddnode.clone();
122
+ }
123
+ let x = bddmgr.var(&name);
124
+ let v = Var { node: vec![name.clone()], bddnode: x.clone() };
125
+ {
126
+ let mut events = ftmgr.events.borrow_mut();
127
+ events.insert(name.clone(), v);
128
+ }
129
+ x
130
+ }
131
+ FTNode::And { id, args } => {
132
+ if let Some(x) = ftmgr.bddnode.borrow().get(id) {
133
+ return x.clone();
134
+ }
135
+ let mut b = Vec::new();
136
+ for arg in args.iter() {
137
+ let tmp = Self::create(mgr, bddmgr, arg.clone());
138
+ b.push(tmp);
139
+ }
140
+ let x = bddmgr.and(b);
141
+ {
142
+ let mut bddnodes = ftmgr.bddnode.borrow_mut();
143
+ bddnodes.insert(*id, x.clone());
144
+ }
145
+ x
146
+ }
147
+ FTNode::Or { id, args } => {
148
+ if let Some(x) = ftmgr.bddnode.borrow().get(id) {
149
+ return x.clone();
150
+ }
151
+ let mut b = Vec::new();
152
+ for arg in args.iter() {
153
+ let tmp = Self::create(mgr, bddmgr, arg.clone());
154
+ b.push(tmp);
155
+ }
156
+ let x = bddmgr.or(b);
157
+ {
158
+ let mut bddnodes = ftmgr.bddnode.borrow_mut();
159
+ bddnodes.insert(*id, x.clone());
160
+ }
161
+ x
162
+ }
163
+ FTNode::KofN { id, k, args } => {
164
+ if let Some(x) = ftmgr.bddnode.borrow().get(id) {
165
+ return x.clone();
166
+ }
167
+ let mut b = Vec::new();
168
+ for arg in args.iter() {
169
+ let tmp = Self::create(mgr, bddmgr, arg.clone());
170
+ b.push(tmp);
171
+ }
172
+ let x = bddmgr.kofn(*k, b);
173
+ {
174
+ let mut bddnodes = ftmgr.bddnode.borrow_mut();
175
+ bddnodes.insert(*id, x.clone());
176
+ }
177
+ x
178
+ }
179
+ }
180
+ }
181
+
182
+ }
183
+
184
+ #[pyclass(unsendable)]
185
+ pub struct FtMgr {
186
+ ftmgr: Rc<RefCell<FTMgr>>,
187
+ }
188
+
189
+ #[pymethods]
190
+ impl FtMgr {
191
+ #[new]
192
+ pub fn new() -> FtMgr {
193
+ FtMgr {
194
+ ftmgr: Rc::new(RefCell::new(FTMgr::new())),
195
+ }
196
+ }
197
+
198
+ pub fn basic(&self, name: &str) -> FtNode {
199
+ FTMgr::basic(&self.ftmgr, name)
200
+ }
201
+
202
+ pub fn repeat(&self, name: &str) -> FtNode {
203
+ FTMgr::repeat(&self.ftmgr, name)
204
+ }
205
+
206
+ pub fn and(&self, args: Vec<FtNode>) -> FtNode {
207
+ FTMgr::and(&self.ftmgr, args)
208
+ }
209
+
210
+ pub fn or(&self, args: Vec<FtNode>) -> FtNode {
211
+ FTMgr::or(&self.ftmgr, args)
212
+ }
213
+
214
+ pub fn kofn(&self, k: usize, args: Vec<FtNode>) -> FtNode {
215
+ FTMgr::kofn(&self.ftmgr, k, args)
216
+ }
217
+ }
218
+
219
+ #[pyclass(unsendable)]
220
+ #[derive(Clone)]
221
+ pub struct FtNode {
222
+ ftmgr: Weak<RefCell<FTMgr>>,
223
+ node: Rc<FTNode>,
224
+ }
225
+
226
+ impl FtNode {
227
+ fn new(ftmgr: Rc<RefCell<FTMgr>>, node: Rc<FTNode>) -> Self {
228
+ FtNode {
229
+ ftmgr: Rc::downgrade(&ftmgr),
230
+ node: node,
231
+ }
232
+ }
233
+
234
+ pub fn ftmgr(&self) -> Rc<RefCell<FTMgr>> {
235
+ self.ftmgr.upgrade().unwrap()
236
+ }
237
+
238
+ pub fn node(&self) -> Rc<FTNode> {
239
+ self.node.clone()
240
+ }
241
+ }
242
+
243
+ #[pymethods]
244
+ impl FtNode {
245
+ fn __repr__(&self) -> String {
246
+ match self.node.as_ref() {
247
+ FTNode::Basic { name, .. } => name.clone(),
248
+ FTNode::Repeat { name, .. } => name.clone(),
249
+ FTNode::And { args, .. } => args.iter().map(|x| x.__repr__()).collect::<Vec<String>>().join(" & "),
250
+ FTNode::Or { args, .. } => args.iter().map(|x| x.__repr__()).collect::<Vec<String>>().join(" | "),
251
+ FTNode::KofN { k, args, .. } => format!("{} of {}", k, args.iter().map(|x| x.__repr__()).collect::<Vec<String>>().join(" | ")),
252
+ }
253
+ }
254
+
255
+ fn __and__(&self, other: &FtNode) -> FtNode {
256
+ let ftmgr = self.ftmgr();
257
+ let args = vec![self.clone(), other.clone()];
258
+ FTMgr::and(&ftmgr, args)
259
+ }
260
+
261
+ fn __or__(&self, other: &FtNode) -> FtNode {
262
+ let ftmgr = self.ftmgr();
263
+ let args = vec![self.clone(), other.clone()];
264
+ FTMgr::or(&ftmgr, args)
265
+ }
266
+
267
+ pub fn compile(&self, bddmgr: &mut pybdd::BddMgr) -> pybdd::BddNode {
268
+ let ftmgr = self.ftmgr();
269
+ FTMgr::create(&ftmgr, bddmgr, self.clone())
270
+ }
271
+ }
272
+
273
+ #[pyfunction]
274
+ pub fn ftkofn(k: usize, args: Vec<FtNode>) -> FtNode {
275
+ let ftmgr = args[0].ftmgr();
276
+ FTMgr::kofn(&ftmgr, k, args)
277
+ }
@@ -0,0 +1,6 @@
1
+ pub mod ft;
2
+ pub mod bdd;
3
+
4
+ pub mod ftnode;
5
+
6
+ pub mod pymod;
@@ -0,0 +1,24 @@
1
+ use pyo3::prelude::*;
2
+ use pyo3::wrap_pyfunction;
3
+
4
+ use crate::bdd::BddMgr;
5
+ use crate::bdd::BddNode;
6
+
7
+ use crate::bdd::kofn;
8
+ use crate::bdd::ifelse;
9
+
10
+ use crate::ftnode::FtMgr;
11
+ use crate::ftnode::FtNode;
12
+ use crate::ftnode::ftkofn;
13
+
14
+ #[pymodule]
15
+ pub fn relibmss(_py: Python, m: &PyModule) -> PyResult<()> {
16
+ m.add_class::<BddNode>()?;
17
+ m.add_class::<BddMgr>()?;
18
+ m.add_function(wrap_pyfunction!(ifelse, m)?)?;
19
+ m.add_function(wrap_pyfunction!(kofn, m)?)?;
20
+ m.add_class::<FtNode>()?;
21
+ m.add_class::<FtMgr>()?;
22
+ m.add_function(wrap_pyfunction!(ftkofn, m)?)?;
23
+ Ok(())
24
+ }
@@ -0,0 +1,100 @@
1
+ import relibmss as ms
2
+
3
+ def test_test2():
4
+ ft = ms.FtMgr()
5
+ c = [ft.repeat("c" + str(i)) for i in range(61)]
6
+
7
+ g62 = c[0] & c[1]
8
+ g63 = c[0] & c[2]
9
+ g64 = c[0] & c[3]
10
+ g65 = c[0] & c[4]
11
+ g66 = c[0] & c[5]
12
+ g67 = c[0] & c[6]
13
+ g68 = c[0] & c[7]
14
+ g69 = c[0] & c[8]
15
+ g70 = g62 | c[9]
16
+ g71 = g63 | c[10]
17
+ g72 = g64 | c[11]
18
+ g73 = g65 | c[12]
19
+ g74 = g62 | c[13]
20
+ g75 = g63 | c[14]
21
+ g76 = g64 | c[15]
22
+ g77 = g65 | c[16]
23
+ g78 = g62 | c[17]
24
+ g79 = g63 | c[18]
25
+ g80 = g64 | c[19]
26
+ g81 = g65 | c[20]
27
+ g82 = g62 | c[21]
28
+ g83 = g63 | c[22]
29
+ g84 = g64 | c[23]
30
+ g85 = g65 | c[24]
31
+ g86 = g62 | c[25]
32
+ g87 = g63 | c[26]
33
+ g88 = g64 | c[27]
34
+ g89 = g65 | c[28]
35
+ g90 = g66 | c[29]
36
+ g91 = g68 | c[30]
37
+ g92 = g67 | c[31]
38
+ g93 = g69 | c[32]
39
+ g94 = g66 | c[33]
40
+ g95 = g68 | c[34]
41
+ g96 = g67 | c[35]
42
+ g97 = g69 | c[36]
43
+ g98 = g66 | c[37]
44
+ g99 = g68 | c[38]
45
+ g100 = g67 | c[39]
46
+ g101 = g69 | c[40]
47
+ g102 = g66 | c[41]
48
+ g103 = g68 | c[42]
49
+ g104 = g67 | c[43]
50
+ g105 = g69 | c[44]
51
+ g106 = ms.ftkofn(3, [g70, g71, g72, g73])
52
+ g107 = ms.ftkofn(3, [g74, g75, g76, g77])
53
+ g108 = ms.ftkofn(3, [g78, g79, g80, g81])
54
+ g109 = ms.ftkofn(3, [g82, g83, g84, g85])
55
+ g110 = ms.ftkofn(3, [g86, g87, g88, g89])
56
+ g111 = ms.ftkofn(3, [g94, g95, g96, g97])
57
+ g112 = ms.ftkofn(3, [g98, g99, g100, g101])
58
+ g113 = g90 & g92
59
+ g114 = g91 & g93
60
+ g115 = g102 & g104
61
+ g116 = g103 & g105
62
+ g117 = g113 | c[45]
63
+ g118 = g114 | c[46]
64
+ g119 = g107 | g108 | c[51]
65
+ g120 = g109 | g110
66
+ g121 = g66 | g117 | c[47]
67
+ g122 = g68 | g118 | c[48]
68
+ g123 = g67 | g117 | c[49]
69
+ g124 = g69 | g118 | c[50]
70
+ g125 = ms.ftkofn(2, [g121, g123, g122, g124])
71
+ g126 = g111 | g112 | g125 | c[52]
72
+ g127 = g115 & g120
73
+ g128 = g116 & g120
74
+ g129 = g62 | g127 | c[53]
75
+ g130 = g63 | g128 | c[54]
76
+ g131 = g64 | g127 | c[55]
77
+ g132 = g65 | g128 | c[56]
78
+ g133 = g62 | g129 | c[57]
79
+ g134 = g63 | g130 | c[58]
80
+ g135 = g64 | g131 | c[59]
81
+ g136 = g65 | g132 | c[60]
82
+ g137 = ms.ftkofn(3, [g133, g134, g135, g136])
83
+ g138 = g106 | g119 | g137
84
+ g139 = g62 | g66 | g117 | g129 | c[47]
85
+ g140 = g63 | g68 | g118 | g130 | c[48]
86
+ g141 = g64 | g67 | g117 | g131 | c[49]
87
+ g142 = g65 | g69 | g118 | g132 | c[50]
88
+ g143 = g139 & g140 & g141 & g142
89
+ g144 = g111 | g112 | g143 | c[52]
90
+ top = g126 & g138 & g144
91
+
92
+ # print(g116)
93
+
94
+ bdd = ms.BddMgr()
95
+ # x = top.compile(bdd)
96
+ # print(x.count())
97
+ x = top.compile(bdd)
98
+ print(x.count())
99
+ m = x.mcs()
100
+ print(m.extract())
@@ -0,0 +1,104 @@
1
+ import relibmss as ms
2
+
3
+ # def test_test1():
4
+ # bdd = ms.BddMgr()
5
+ # c = bdd.vars(["c" + str(i) for i in range(61)])
6
+
7
+ # g62 = c[0] & c[1]
8
+ # g63 = c[0] & c[2]
9
+ # g64 = c[0] & c[3]
10
+ # g65 = c[0] & c[4]
11
+ # g66 = c[0] & c[5]
12
+ # g67 = c[0] & c[6]
13
+ # g68 = c[0] & c[7]
14
+ # g69 = c[0] & c[8]
15
+ # g70 = g62 | c[9]
16
+ # g71 = g63 | c[10]
17
+ # g72 = g64 | c[11]
18
+ # g73 = g65 | c[12]
19
+ # g74 = g62 | c[13]
20
+ # g75 = g63 | c[14]
21
+ # g76 = g64 | c[15]
22
+ # g77 = g65 | c[16]
23
+ # g78 = g62 | c[17]
24
+ # g79 = g63 | c[18]
25
+ # g80 = g64 | c[19]
26
+ # g81 = g65 | c[20]
27
+ # g82 = g62 | c[21]
28
+ # g83 = g63 | c[22]
29
+ # g84 = g64 | c[23]
30
+ # g85 = g65 | c[24]
31
+ # g86 = g62 | c[25]
32
+ # g87 = g63 | c[26]
33
+ # g88 = g64 | c[27]
34
+ # g89 = g65 | c[28]
35
+ # g90 = g66 | c[29]
36
+ # g91 = g68 | c[30]
37
+ # g92 = g67 | c[31]
38
+ # g93 = g69 | c[32]
39
+ # g94 = g66 | c[33]
40
+ # g95 = g68 | c[34]
41
+ # g96 = g67 | c[35]
42
+ # g97 = g69 | c[36]
43
+ # g98 = g66 | c[37]
44
+ # g99 = g68 | c[38]
45
+ # g100 = g67 | c[39]
46
+ # g101 = g69 | c[40]
47
+ # g102 = g66 | c[41]
48
+ # g103 = g68 | c[42]
49
+ # g104 = g67 | c[43]
50
+ # g105 = g69 | c[44]
51
+ # g106 = ms.kofn(3, [g70, g71, g72, g73])
52
+ # g107 = ms.kofn(3, [g74, g75, g76, g77])
53
+ # g108 = ms.kofn(3, [g78, g79, g80, g81])
54
+ # g109 = ms.kofn(3, [g82, g83, g84, g85])
55
+ # g110 = ms.kofn(3, [g86, g87, g88, g89])
56
+ # g111 = ms.kofn(3, [g94, g95, g96, g97])
57
+ # g112 = ms.kofn(3, [g98, g99, g100, g101])
58
+ # g113 = g90 & g92
59
+ # g114 = g91 & g93
60
+ # g115 = g102 & g104
61
+ # g116 = g103 & g105
62
+ # g117 = g113 | c[45]
63
+ # g118 = g114 | c[46]
64
+ # g119 = g107 | g108 | c[51]
65
+ # g120 = g109 | g110
66
+ # g121 = g66 | g117 | c[47]
67
+ # g122 = g68 | g118 | c[48]
68
+ # g123 = g67 | g117 | c[49]
69
+ # g124 = g69 | g118 | c[50]
70
+ # g125 = ms.kofn(2, [g121, g123, g122, g124])
71
+ # g126 = g111 | g112 | g125 | c[52]
72
+ # g127 = g115 & g120
73
+ # g128 = g116 & g120
74
+ # g129 = g62 | g127 | c[53]
75
+ # g130 = g63 | g128 | c[54]
76
+ # g131 = g64 | g127 | c[55]
77
+ # g132 = g65 | g128 | c[56]
78
+ # g133 = g62 | g129 | c[57]
79
+ # g134 = g63 | g130 | c[58]
80
+ # g135 = g64 | g131 | c[59]
81
+ # g136 = g65 | g132 | c[60]
82
+ # g137 = ms.kofn(3, [g133, g134, g135, g136])
83
+ # g138 = g106 | g119 | g137
84
+
85
+ # assert bdd.size() > 0 # 簡単なチェックとしてBDDのサイズが0でないことを確認
86
+ # n = g138.mcs()
87
+ # assert n is not None # mcsの結果がNoneでないことを確認
88
+
89
+ def test_test2():
90
+ bdd = ms.BddMgr()
91
+ x, y, z = bdd.vars(["x", "y", "z"])
92
+ v = bdd.rpn("x y z & &")
93
+ assert v is not None # RPN結果がNoneでないことを確認
94
+
95
+ n = v.mcs()
96
+ print(n.dot())
97
+ print(n.extract())
98
+ assert n is not None # MCS結果がNoneでないことを確認
99
+
100
+ probability = v.prob({"x": 0.1, "y": 0.2, "z": 0.01})
101
+ assert 0 <= probability <= 1 # 確率が妥当な範囲内であることを確認
102
+
103
+ extracted = n.extract()
104
+ assert extracted is not None # 抽出結果がNoneでないことを確認