EPICProver 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.
epiclogic/__init__.py ADDED
@@ -0,0 +1,61 @@
1
+ """Modal logic symbolic library."""
2
+ import os
3
+ import importlib
4
+
5
+ from .kernel import operators
6
+ from .kernel.opertree import (
7
+ opertree, str_tree
8
+ )
9
+ from .kernel.proofTree import (
10
+ proofTree,
11
+ isDerived
12
+ )
13
+ from .utils.derivedFormula import (
14
+ derivedFormula
15
+ )
16
+ from .utils.inferenceRule import (
17
+ inferenceRule
18
+ )
19
+ from .utils.provenTheorem import (
20
+ provenTheorem,
21
+ proven_theorems
22
+ )
23
+
24
+ current_dir = os.path.dirname(__file__)
25
+ strategy_dir = os.path.join(current_dir, 'strategy')
26
+
27
+ strategy = []
28
+ if os.path.exists(strategy_dir):
29
+ strategy = [
30
+ (x[:-3] if x.endswith('.py') else x)
31
+ for x in os.listdir(strategy_dir)
32
+ if not x.startswith('__') and not x.startswith('.')
33
+ ]
34
+
35
+ __all__ = [
36
+ #operators
37
+ 'operators',
38
+
39
+ #opertree
40
+ 'opertree',
41
+ 'str_tree',
42
+
43
+ #proofTree
44
+ 'proofTree',
45
+ 'isDerived',
46
+
47
+ #derivedFormula
48
+ 'derivedFormula',
49
+
50
+ #inferenceRule
51
+ 'inferenceRule',
52
+
53
+ #provenTheorem
54
+ 'provenTheorem',
55
+ 'proven_theorems'
56
+ ]
57
+
58
+ for st in strategy:
59
+ module = importlib.import_module(f".strategy.{st}", package=__name__)
60
+ globals()[st] = module
61
+ __all__.append(st)
@@ -0,0 +1,153 @@
1
+ class dequenode:
2
+ """A node in a doubly linked list (deque) with manual link management.
3
+
4
+ This class represents a node that stores a value and references to its
5
+ left and right neighbors. Unlike collections.deque, this implementation
6
+ gives the user full control over node links, allowing O(1) insertion and
7
+ removal at arbitrary positions (not just at ends).
8
+
9
+ Links are managed via the `left` and `right` properties, which
10
+ automatically update the corresponding neighbor's opposite link.
11
+
12
+ Attributes:
13
+ value (object): The payload stored in the node.
14
+ _left (dequenode | None): Internal reference to the left neighbor.
15
+ _right (dequenode | None): Internal reference to the right neighbor.
16
+
17
+ Properties:
18
+ left (dequenode | None): Left neighbor (get/set). Setting updates the
19
+ neighbor's right link.
20
+ right (dequenode | None): Right neighbor (get/set). Setting updates the
21
+ neighbor's left link.
22
+
23
+ Examples:
24
+ >>> a = dequenode('a')
25
+ >>> b = dequenode('b', a) # b.left = a, a.right = b
26
+ >>> c = dequenode('c', b) # c.left = b, b.right = c
27
+ >>> d = dequenode('d')
28
+ >>> c.right = d # c.right = d, d.left = c"""
29
+
30
+ __slots__ = ('value', '_left', '_right')
31
+
32
+ def __init__(self, value: object, left: 'dequenode|None' = None, right: 'dequenode|None' = None):
33
+ self.value = value
34
+ self._left = self._right = None
35
+ self.left = left
36
+ self.right = right
37
+
38
+ def of(elems: 'iterable', index: int = 0, cycle: bool = False) -> 'deque':
39
+ res = cur = None
40
+ for elem in elems:
41
+ if res is None:
42
+ res = cur = dequenode(elem)
43
+ elif cur.right is None:
44
+ cur.right = dequenode(elem)
45
+ cur = cur.right
46
+ if cycle:
47
+ cur.right = res
48
+ for _ in range(index):
49
+ if not res.right is None:
50
+ res = res.right
51
+ else:
52
+ raise IndexError('deque index out of range')
53
+ return res
54
+
55
+ @property
56
+ def left(self):
57
+ return self._left
58
+
59
+ @left.setter
60
+ def left(self, value: 'dequenode|None'):
61
+ if value is None:
62
+ if not self._left is None:
63
+ self._left._right = None
64
+ self._left = None
65
+ elif isinstance(value, dequenode):
66
+ if not self._left is None:
67
+ self._left._right = None
68
+ self._left = value
69
+ if not value._right is None:
70
+ value._right._left = None
71
+ value._right = self
72
+ else:
73
+ raise TypeError(f'must be "dequenode", not a "{type(value).__name__}"')
74
+
75
+ @property
76
+ def right(self):
77
+ return self._right
78
+
79
+ @right.setter
80
+ def right(self, value: 'dequenode|None'):
81
+ if value is None:
82
+ if not self._right is None:
83
+ self._right._left = None
84
+ self._right = None
85
+ elif isinstance(value, dequenode):
86
+ if not self._right is None:
87
+ self._right._left = None
88
+ self._right = value
89
+ if not value._left is None:
90
+ value._left._right = None
91
+ value._left = self
92
+ else:
93
+ raise TypeError(f'must be "dequenode", not a "{type(value).__name__}"')
94
+
95
+ def __str__(self):
96
+ res = f'<->[{self.value}]<->'
97
+ cur = self
98
+ while not (
99
+ (cur := cur.left) is None or
100
+ cur is self
101
+ ):
102
+ res = f'<->({cur.value})' + res
103
+ if cur is None:
104
+ res = 'None' + res
105
+ else:
106
+ res = f'...<->[{cur.value}]' + res
107
+ cur = self
108
+ while not (
109
+ (cur := cur.right) is None or
110
+ cur is self
111
+ ):
112
+ res += f'({cur.value})<->'
113
+ if cur is None:
114
+ res += 'None'
115
+ else:
116
+ res += f'[{cur.value}]<->...'
117
+ return res
118
+
119
+ def __repr__(self):
120
+ prev = cur = self
121
+ index = 0
122
+ while not (
123
+ (cur := cur.left) is None or
124
+ cur is self
125
+ ):
126
+ prev = cur
127
+ index += 1
128
+ if cur is self:
129
+ res = [cur.value]
130
+ while not (cur := cur.right) is self:
131
+ res.append(cur.value)
132
+ return f'dequenode.of({res!r}, 0, True)'
133
+ else:
134
+ cur = prev
135
+ res = [cur.value]
136
+ while not (cur := cur.right) is None:
137
+ res.append(cur.value)
138
+ return f'dequenode.of({res!r}, {index})'
139
+
140
+ if __name__ == '__main__':
141
+ a = dequenode('a')
142
+ b = dequenode('b', a)
143
+ c = dequenode('c', b)
144
+ d = c.right = dequenode('d')
145
+ print(a, b, c, d, sep = '\n')
146
+ print(f'{a!r}\n{b!r}\n{c!r}\n{d!r}')
147
+ d.right = a
148
+ print(a, b, c, d, sep = '\n')
149
+ print(f'{a!r}\n{b!r}\n{c!r}\n{d!r}')
150
+ b.left = b.left.left
151
+ b.right = b.right.right
152
+ print(a, b, c, d, sep = '\n')
153
+ print(f'{a!r}\n{b!r}\n{c!r}\n{d!r}')