link-rep 0.0.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.
link_rep-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TopologicalKnotIndexer
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.
@@ -0,0 +1,156 @@
1
+ Metadata-Version: 2.4
2
+ Name: link-rep
3
+ Version: 0.0.1
4
+ Summary: representation for a composite topological link.
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Author: GGN_2015
8
+ Author-email: premierbob@qq.com
9
+ Requires-Python: >=3.10
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Requires-Dist: typing_extensions
18
+ Description-Content-Type: text/markdown
19
+
20
+ # LinkRep
21
+ A Cross-Platform Universal Representation for Composite Links
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install link-rep
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ```python
32
+ from link_rep import LinkRep
33
+
34
+ real_serial = ( # human readable presentation
35
+ """
36
+ // this is comment line 1
37
+ // this is comment line 2
38
+ L2a1: [[4, 1, 3, 2], [2, 3, 1, 4]]
39
+ L4a1: [[6, 1, 7, 2], [8, 3, 5, 4], [2, 5, 3, 6], [4, 7, 1, 8]]
40
+ K3a1: [[1, 5, 2, 4], [3, 1, 4, 6], [5, 3, 6, 2]]
41
+ [L2a1, L4a1, K3a1]
42
+ L[1, 1]#L[2, 1]
43
+ L[2, 2]#L[3, 1]
44
+ """).lstrip()
45
+
46
+ link_r = LinkRep()
47
+ link_r.deserialize(real_serial)
48
+
49
+ print(link_r.json_serialize()) # machine readable presentation
50
+ print(link_r.serialize()) # human readable presentation
51
+
52
+ json_str = link_r.json_serialize()
53
+ new_link_r = LinkRep()
54
+ new_link_r.json_deserialize(json_str) # get data from json serial
55
+ ```
56
+
57
+ ## LinkRep Format
58
+
59
+ The content of LinkRep consists of four parts:
60
+
61
+ 1. Comment Lines: Lines starting with `//`, as well as lines containing only whitespace characters, are comment lines. Lines containing only whitespace should be ignored during parsing, while comment lines should be retained as informational content.
62
+
63
+ 2. Variable Definitions (VarDef): Used to define variables that represent PdCodes (Planar Diagram Codes), for example:
64
+
65
+ ```
66
+ L2a1: [[4, 1, 3, 2], [2, 3, 1, 4]]
67
+ ```
68
+
69
+ The above statement defines a variable named `L2a1` that stores a PdCode `[[4, 1, 3, 2], [2, 3, 1, 4]]`. The variable name (VarName) should be a string composed of letters, numbers, and underscores, and must not start with a number. Multiple variables with different names can be defined.
70
+
71
+ While the rules allow arbitrary variable naming, in practice it is recommended to use standard knot or link names to name PdCodes. Warnings should be issued for variable definitions using non-standard PdCodes.
72
+
73
+ 3. Link Set Description (LinkSet): A sequence of variable names describing all links used, where the order affects subsequent usage. This description can only appear once in LinkRep.
74
+
75
+ ```
76
+ [L2a1, L4a1, K3a1]
77
+ ```
78
+
79
+ This line describes the knot information before performing connected sums. In the connection method descriptor, `L[i, j]` is used to denote the j-th connected component of the i-th link variable. Both `i` and `j` are numbered starting from 1 and increment upwards.
80
+
81
+ 4. Connection Method Descriptor (LinkMethod): Describes which connected components of which links should be connected together, for example:
82
+
83
+ ```
84
+ L[1, 1]#L[2, 2]
85
+ ```
86
+
87
+ This can be used to indicate that the first connected component of the first link should be connected (via connected sum) with the second connected component of the second link.
88
+
89
+ ```
90
+ L[1, 2]#L[2, 2]#L[3, 1]
91
+ ```
92
+
93
+ This can be used to indicate that the second connected component of the first link should be connected (via connected sum) with the second connected component of the second link, and this connected component should then be connected (via connected sum) with the first connected component of the third link.
94
+
95
+ ## Formal Definition
96
+
97
+ Lexical Units:
98
+ ```
99
+ CommentLine => "//[^\n]*\n"
100
+ VarName => "[A-Za-z_][A-Za-z0-9_]*"
101
+ PdCode => "(\[\])|(\[\[\d+,\s*\d+,\s*\d+,\s*\d+\](,\[\d+,\s*\d+,\s*\d+,\s*\d+\])*\])"
102
+ PosName => "L\[\d+,\s*\d+\]"
103
+ ```
104
+
105
+ VarLine: Defines a single variable
106
+ ```
107
+ VarLine -> VarName ":" PdCode "\n"
108
+ ```
109
+
110
+ VarDef: Defines all variables
111
+ ```
112
+ VarDef -> VarLine
113
+ VarDef -> VarLine VarDef
114
+ ```
115
+
116
+ VarNameList: List of variable names
117
+ ```
118
+ VarNameList -> VarName
119
+ VarNameList -> VarName "," VarNameList
120
+ ```
121
+
122
+ LinkSet: Defines all links to be used
123
+ ```
124
+ LinkSet -> "[" VarNameList "]" "\n"
125
+ ```
126
+
127
+ LinkLineList: Connects connected components without line breaks
128
+ ```
129
+ LinkLineList -> PosName "#" PosName
130
+ LinkLineList -> PosName "#" PosName "#" LinkLineList
131
+ ```
132
+
133
+ LinkLine: Describes the connection of connected components
134
+ ```
135
+ LinkLine -> LinkLineList "\n"
136
+ ```
137
+
138
+ LinkMethod: Describes the connection of connected components
139
+ ```
140
+ LinkMethod ->
141
+ LinkMethod -> LinkLine
142
+ LinkMethod -> LinkLine LinkMethod
143
+ ```
144
+
145
+ Comment:
146
+ ```
147
+ Comment ->
148
+ Comment -> CommentLine
149
+ Comment -> CommentLine Comment
150
+ ```
151
+
152
+ LinkRep:
153
+ ```
154
+ LinkRep -> Comment VarDef LinkSet LinkMethod
155
+ ```
156
+
@@ -0,0 +1,136 @@
1
+ # LinkRep
2
+ A Cross-Platform Universal Representation for Composite Links
3
+
4
+ ## Installation
5
+
6
+ ```bash
7
+ pip install link-rep
8
+ ```
9
+
10
+ ## Usage
11
+
12
+ ```python
13
+ from link_rep import LinkRep
14
+
15
+ real_serial = ( # human readable presentation
16
+ """
17
+ // this is comment line 1
18
+ // this is comment line 2
19
+ L2a1: [[4, 1, 3, 2], [2, 3, 1, 4]]
20
+ L4a1: [[6, 1, 7, 2], [8, 3, 5, 4], [2, 5, 3, 6], [4, 7, 1, 8]]
21
+ K3a1: [[1, 5, 2, 4], [3, 1, 4, 6], [5, 3, 6, 2]]
22
+ [L2a1, L4a1, K3a1]
23
+ L[1, 1]#L[2, 1]
24
+ L[2, 2]#L[3, 1]
25
+ """).lstrip()
26
+
27
+ link_r = LinkRep()
28
+ link_r.deserialize(real_serial)
29
+
30
+ print(link_r.json_serialize()) # machine readable presentation
31
+ print(link_r.serialize()) # human readable presentation
32
+
33
+ json_str = link_r.json_serialize()
34
+ new_link_r = LinkRep()
35
+ new_link_r.json_deserialize(json_str) # get data from json serial
36
+ ```
37
+
38
+ ## LinkRep Format
39
+
40
+ The content of LinkRep consists of four parts:
41
+
42
+ 1. Comment Lines: Lines starting with `//`, as well as lines containing only whitespace characters, are comment lines. Lines containing only whitespace should be ignored during parsing, while comment lines should be retained as informational content.
43
+
44
+ 2. Variable Definitions (VarDef): Used to define variables that represent PdCodes (Planar Diagram Codes), for example:
45
+
46
+ ```
47
+ L2a1: [[4, 1, 3, 2], [2, 3, 1, 4]]
48
+ ```
49
+
50
+ The above statement defines a variable named `L2a1` that stores a PdCode `[[4, 1, 3, 2], [2, 3, 1, 4]]`. The variable name (VarName) should be a string composed of letters, numbers, and underscores, and must not start with a number. Multiple variables with different names can be defined.
51
+
52
+ While the rules allow arbitrary variable naming, in practice it is recommended to use standard knot or link names to name PdCodes. Warnings should be issued for variable definitions using non-standard PdCodes.
53
+
54
+ 3. Link Set Description (LinkSet): A sequence of variable names describing all links used, where the order affects subsequent usage. This description can only appear once in LinkRep.
55
+
56
+ ```
57
+ [L2a1, L4a1, K3a1]
58
+ ```
59
+
60
+ This line describes the knot information before performing connected sums. In the connection method descriptor, `L[i, j]` is used to denote the j-th connected component of the i-th link variable. Both `i` and `j` are numbered starting from 1 and increment upwards.
61
+
62
+ 4. Connection Method Descriptor (LinkMethod): Describes which connected components of which links should be connected together, for example:
63
+
64
+ ```
65
+ L[1, 1]#L[2, 2]
66
+ ```
67
+
68
+ This can be used to indicate that the first connected component of the first link should be connected (via connected sum) with the second connected component of the second link.
69
+
70
+ ```
71
+ L[1, 2]#L[2, 2]#L[3, 1]
72
+ ```
73
+
74
+ This can be used to indicate that the second connected component of the first link should be connected (via connected sum) with the second connected component of the second link, and this connected component should then be connected (via connected sum) with the first connected component of the third link.
75
+
76
+ ## Formal Definition
77
+
78
+ Lexical Units:
79
+ ```
80
+ CommentLine => "//[^\n]*\n"
81
+ VarName => "[A-Za-z_][A-Za-z0-9_]*"
82
+ PdCode => "(\[\])|(\[\[\d+,\s*\d+,\s*\d+,\s*\d+\](,\[\d+,\s*\d+,\s*\d+,\s*\d+\])*\])"
83
+ PosName => "L\[\d+,\s*\d+\]"
84
+ ```
85
+
86
+ VarLine: Defines a single variable
87
+ ```
88
+ VarLine -> VarName ":" PdCode "\n"
89
+ ```
90
+
91
+ VarDef: Defines all variables
92
+ ```
93
+ VarDef -> VarLine
94
+ VarDef -> VarLine VarDef
95
+ ```
96
+
97
+ VarNameList: List of variable names
98
+ ```
99
+ VarNameList -> VarName
100
+ VarNameList -> VarName "," VarNameList
101
+ ```
102
+
103
+ LinkSet: Defines all links to be used
104
+ ```
105
+ LinkSet -> "[" VarNameList "]" "\n"
106
+ ```
107
+
108
+ LinkLineList: Connects connected components without line breaks
109
+ ```
110
+ LinkLineList -> PosName "#" PosName
111
+ LinkLineList -> PosName "#" PosName "#" LinkLineList
112
+ ```
113
+
114
+ LinkLine: Describes the connection of connected components
115
+ ```
116
+ LinkLine -> LinkLineList "\n"
117
+ ```
118
+
119
+ LinkMethod: Describes the connection of connected components
120
+ ```
121
+ LinkMethod ->
122
+ LinkMethod -> LinkLine
123
+ LinkMethod -> LinkLine LinkMethod
124
+ ```
125
+
126
+ Comment:
127
+ ```
128
+ Comment ->
129
+ Comment -> CommentLine
130
+ Comment -> CommentLine Comment
131
+ ```
132
+
133
+ LinkRep:
134
+ ```
135
+ LinkRep -> Comment VarDef LinkSet LinkMethod
136
+ ```
@@ -0,0 +1,68 @@
1
+ from typing_extensions import override
2
+ import json
3
+
4
+ try:
5
+ from .LinkRepMetaObject import LinkRepMetaObject
6
+ except:
7
+ from LinkRepMetaObject import LinkRepMetaObject
8
+
9
+ # 注释部分:记录每一行的注释信息
10
+ # 存储的注释信息中不含 "//" 与行末的换行符
11
+ class Comment(LinkRepMetaObject):
12
+ def __init__(self) -> None:
13
+ super().__init__()
14
+ self.msg_list = []
15
+
16
+ # 设置注释内容
17
+ def set_msg_list(self, new_msg_list:list[str]):
18
+ # 需要删除所有换行符
19
+ self.msg_list = list(map(
20
+ lambda line: line.replace("\n", ""),
21
+ new_msg_list
22
+ ))
23
+
24
+ @override
25
+ def serialize(self) -> str:
26
+ return "".join(list(map(
27
+ lambda line: "//" + line + "\n",
28
+ self.msg_list
29
+ )))
30
+
31
+ @override
32
+ def deserialize(self, s:str) -> None:
33
+ self.set_msg_list([
34
+ item[2:]
35
+ for item in s.split("\n")
36
+ if item.startswith("//")
37
+ ])
38
+
39
+ @override
40
+ def json_serialize(self) -> str:
41
+ return json.dumps({
42
+ "type": "Comment",
43
+ "msg_list": self.msg_list
44
+ })
45
+
46
+ @override
47
+ def json_deserialize(self, s:str) -> None:
48
+ obj_now = json.loads(s)
49
+
50
+ # 控制类型
51
+ if obj_now.get("type") != "Comment":
52
+ raise AssertionError()
53
+
54
+ # 必须包含完整信息
55
+ if not isinstance(obj_now.get("msg_list"), list):
56
+ raise AssertionError()
57
+
58
+ # 设置元素内容
59
+ self.set_msg_list(obj_now["msg_list"])
60
+
61
+ if __name__ == "__main__":
62
+ ser = """//line1
63
+ //line2
64
+ //line3"""
65
+
66
+ obj = Comment()
67
+ obj.deserialize(ser)
68
+ print(obj.json_serialize())
@@ -0,0 +1,82 @@
1
+ from typing_extensions import override
2
+ import json
3
+
4
+ try:
5
+ from .LinkRepMetaObject import LinkRepMetaObject
6
+ from .LinkTerm import LinkTerm
7
+ except:
8
+ from LinkRepMetaObject import LinkRepMetaObject
9
+ from LinkTerm import LinkTerm
10
+
11
+ # component list 里面的元素是 LinkTerm
12
+ class LinkMethod(LinkRepMetaObject):
13
+ def __init__(self) -> None:
14
+ super().__init__()
15
+ self.component_list = []
16
+
17
+ # 设置变量名的映射关系
18
+ def set_component_list(self, new_component_list:list[LinkTerm]) -> None:
19
+ self.component_list = new_component_list
20
+ for term in new_component_list:
21
+ if not isinstance(term, LinkTerm):
22
+ raise AssertionError()
23
+
24
+ @override
25
+ def serialize(self) -> str:
26
+ return "".join(list(map(
27
+ lambda link_term: link_term.serialize(),
28
+ self.component_list
29
+ )))
30
+
31
+ @override
32
+ def deserialize(self, s:str) -> None:
33
+ new_arr = []
34
+ for term in s.split("\n"):
35
+ if term.find("#") != -1:
36
+ link_term = LinkTerm()
37
+ link_term.deserialize(term.strip())
38
+ new_arr.append(link_term)
39
+ self.set_component_list(new_arr)
40
+
41
+ @override
42
+ def json_serialize(self) -> str:
43
+ return json.dumps({
44
+ "type": "LinkMethod",
45
+ "component_list": [
46
+ json.loads(link_term.json_serialize())
47
+ for link_term in self.component_list
48
+ ]
49
+ })
50
+
51
+ @override
52
+ def json_deserialize(self, s:str) -> None:
53
+ obj_now = json.loads(s)
54
+
55
+ # 控制类型
56
+ if obj_now.get("type") != "LinkMethod":
57
+ raise AssertionError()
58
+
59
+ # 必须包含完整信息
60
+ if not isinstance(obj_now.get("component_list"), list):
61
+ raise AssertionError()
62
+
63
+ # 为了纯函数编程
64
+ def map_json_val_to_link_term(json_val:dict) -> LinkTerm:
65
+ link_term = LinkTerm()
66
+ link_term.json_deserialize(json.dumps(json_val))
67
+ return link_term
68
+
69
+ # 设置元素内容
70
+ self.set_component_list([
71
+ map_json_val_to_link_term(term)
72
+ for term in obj_now["component_list"]
73
+ ])
74
+
75
+ if __name__ == "__main__":
76
+ var_def = LinkMethod()
77
+ var_def.deserialize("""\nL[1, 2]#L[2, 3]\nL[1, 3]#L[3, 3]\n""")
78
+
79
+ json_str = '{"type": "LinkMethod", "component_list": [{"type": "LinkTerm", "component_list": [[1, 2], [2, 3]]}, {"type": "LinkTerm", "component_list": [[1, 3], [3, 3]]}]}'
80
+ new_link = LinkMethod()
81
+ new_link.json_deserialize(json_str)
82
+ print(new_link.serialize())
@@ -0,0 +1,119 @@
1
+ from typing_extensions import override
2
+ import json
3
+
4
+ try:
5
+ from .LinkRepMetaObject import LinkRepMetaObject
6
+ from .Comment import Comment
7
+ from .VarDef import VarDef
8
+ from .LinkSet import LinkSet
9
+ from .LinkMethod import LinkMethod
10
+ except:
11
+ from LinkRepMetaObject import LinkRepMetaObject
12
+ from Comment import Comment
13
+ from VarDef import VarDef
14
+ from LinkSet import LinkSet
15
+ from LinkMethod import LinkMethod
16
+
17
+ # 存储所有的变量定义
18
+ class LinkRep(LinkRepMetaObject):
19
+ def __init__(self) -> None:
20
+ super().__init__()
21
+ self.comment = Comment()
22
+ self.var_def = VarDef()
23
+ self.link_set = LinkSet()
24
+ self.link_method = LinkMethod()
25
+
26
+ @override
27
+ def serialize(self) -> str:
28
+ return (
29
+ self.comment.serialize() +
30
+ self.var_def.serialize() +
31
+ self.link_set.serialize() +
32
+ self.link_method.serialize()
33
+ )
34
+
35
+ @override
36
+ def deserialize(self, s:str) -> None:
37
+ s = s.strip()
38
+
39
+ comment_list = []
40
+ var_def_list = []
41
+ link_method_list = []
42
+ link_set_list = []
43
+ for line in s.split("\n"):
44
+ line = line.strip()
45
+ if line == "":
46
+ continue
47
+ if line.startswith("//"):
48
+ comment_list.append(line)
49
+ elif line.find(":") != -1:
50
+ var_def_list.append(line)
51
+ elif line.find("#") != -1:
52
+ link_method_list.append(line)
53
+ elif line.startswith("[") and line.endswith("]"):
54
+ link_set_list.append(line)
55
+ else:
56
+ raise AssertionError()
57
+
58
+ if len(link_set_list) != 1:
59
+ raise AssertionError()
60
+
61
+ # 依次对所有元素进行反序列化
62
+ self.comment.deserialize("\n".join(comment_list))
63
+ self.var_def.deserialize("\n".join(var_def_list))
64
+ self.link_set.deserialize(link_set_list[0])
65
+ self.link_method.deserialize("\n".join(link_method_list))
66
+
67
+ @override
68
+ def json_serialize(self) -> str:
69
+ return json.dumps({
70
+ "type": "LinkRep",
71
+ "comment": json.loads(self.comment.json_serialize()),
72
+ "var_def": json.loads(self.var_def.json_serialize()),
73
+ "link_set": json.loads(self.link_set.json_serialize()),
74
+ "link_method": json.loads(self.link_method.json_serialize())
75
+ })
76
+
77
+ @override
78
+ def json_deserialize(self, s:str) -> None:
79
+ obj_now = json.loads(s)
80
+
81
+ # 控制类型
82
+ if obj_now.get("type") != "LinkRep":
83
+ raise AssertionError()
84
+
85
+ # 必须包含完整信息
86
+ for term_name in ["comment", "var_def", "link_set", "link_method"]:
87
+ if not isinstance(obj_now.get(term_name), dict):
88
+ raise AssertionError()
89
+
90
+ instance_now = self.__getattribute__(term_name)
91
+ if not isinstance(instance_now, LinkRepMetaObject):
92
+ raise AssertionError()
93
+ instance_now.json_deserialize(json.dumps(obj_now.get(term_name)))
94
+
95
+ if __name__ == "__main__":
96
+ real_serial = (
97
+ """
98
+ // this is comment line 1
99
+ // this is comment line 2
100
+ L2a1: [[4, 1, 3, 2], [2, 3, 1, 4]]
101
+ L4a1: [[6, 1, 7, 2], [8, 3, 5, 4], [2, 5, 3, 6], [4, 7, 1, 8]]
102
+ K3a1: [[1, 5, 2, 4], [3, 1, 4, 6], [5, 3, 6, 2]]
103
+ [L2a1, L4a1, K3a1]
104
+ L[1, 1]#L[2, 1]
105
+ L[2, 2]#L[3, 1]
106
+ """).lstrip()
107
+
108
+ rev_obj = LinkRep()
109
+ rev_obj.deserialize(real_serial)
110
+ assert rev_obj.serialize() == real_serial
111
+
112
+ json_serialize = rev_obj.json_serialize()
113
+ rev_obj_2 = LinkRep()
114
+ rev_obj_2.json_deserialize(json_serialize)
115
+
116
+ assert rev_obj_2.serialize() == real_serial
117
+ assert rev_obj_2.json_serialize() == rev_obj.json_serialize()
118
+
119
+ print(rev_obj_2.serialize())
@@ -0,0 +1,25 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ class LinkRepMetaObject(ABC):
4
+ def __init__(self) -> None:
5
+ pass
6
+
7
+ # 标准字符串序列号化
8
+ @abstractmethod
9
+ def serialize(self) -> str:
10
+ return ""
11
+
12
+ # 标准字符串反序列化
13
+ @abstractmethod
14
+ def deserialize(self, s:str) -> None:
15
+ return
16
+
17
+ # JSON 字符串序列号化
18
+ @abstractmethod
19
+ def json_serialize(self) -> str:
20
+ return ""
21
+
22
+ # JSON 字符串反序列化
23
+ @abstractmethod
24
+ def json_deserialize(self, s:str) -> None:
25
+ return
@@ -0,0 +1,68 @@
1
+ from typing_extensions import override
2
+ import json
3
+
4
+ try:
5
+ from .LinkRepMetaObject import LinkRepMetaObject
6
+ except:
7
+ from LinkRepMetaObject import LinkRepMetaObject
8
+
9
+ # 存储所有的变量定义
10
+ class LinkSet(LinkRepMetaObject):
11
+ def __init__(self) -> None:
12
+ super().__init__()
13
+ self.var_list = []
14
+
15
+ # 设置变量名的映射关系
16
+ def set_var_list(self, new_var_list:list[str]) -> None:
17
+ self.var_list = new_var_list
18
+
19
+ @override
20
+ def serialize(self) -> str:
21
+ return "[" + ", ".join(self.var_list) + "]\n"
22
+
23
+ @override
24
+ def deserialize(self, s:str) -> None:
25
+ s = s.strip()
26
+
27
+ if not s.startswith("["):
28
+ raise AssertionError()
29
+ if not s.endswith("]"):
30
+ raise AssertionError()
31
+
32
+ self.set_var_list([
33
+ item.strip()
34
+ for item in s[1:-1].split(",")
35
+ ])
36
+
37
+ @override
38
+ def json_serialize(self) -> str:
39
+ return json.dumps({
40
+ "type": "LinkSet",
41
+ "var_list": self.var_list
42
+ })
43
+
44
+ @override
45
+ def json_deserialize(self, s:str) -> None:
46
+ obj_now = json.loads(s)
47
+
48
+ # 控制类型
49
+ if obj_now.get("type") != "LinkSet":
50
+ raise AssertionError()
51
+
52
+ # 必须包含完整信息
53
+ if not isinstance(obj_now.get("var_list"), list):
54
+ raise AssertionError()
55
+
56
+ # 设置元素内容
57
+ self.set_var_list(obj_now["var_list"])
58
+
59
+ if __name__ == "__main__":
60
+ var_def = LinkSet()
61
+ var_def.set_var_list(["L2a1", "L4a1", "K3a1"])
62
+
63
+ ser = var_def.serialize()
64
+ print(ser)
65
+
66
+ new_val = LinkSet()
67
+ new_val.json_deserialize('{"type": "LinkSet", "var_list": ["L2a1", "L4a1", "K3a1"]}')
68
+ print(new_val.json_serialize())
@@ -0,0 +1,79 @@
1
+ from typing_extensions import override
2
+ import json
3
+
4
+ try:
5
+ from .LinkRepMetaObject import LinkRepMetaObject
6
+ except:
7
+ from LinkRepMetaObject import LinkRepMetaObject
8
+
9
+ # 这个 component_list 里面放的东西是一个 list of list
10
+ # 每个 sub_list 中有两个整数,L[i, j] 中的 i, j
11
+ class LinkTerm(LinkRepMetaObject):
12
+ def __init__(self) -> None:
13
+ super().__init__()
14
+ self.component_list = []
15
+
16
+ # 设置变量名的映射关系
17
+ def set_component_list(self, new_component_list:list[list[int]]) -> None:
18
+ self.component_list = new_component_list
19
+ for term in new_component_list:
20
+ if not isinstance(term, list):
21
+ raise AssertionError()
22
+ if len(term) != 2:
23
+ raise AssertionError()
24
+ for sub_term in term:
25
+ if not isinstance(sub_term, int):
26
+ raise AssertionError()
27
+
28
+ @override
29
+ def serialize(self) -> str:
30
+ return "#".join(list(map(
31
+ lambda pr: f"L[{pr[0]}, {pr[1]}]", # 把连通分量编号
32
+ self.component_list
33
+ ))) + "\n"
34
+
35
+ @override
36
+ def deserialize(self, s:str) -> None:
37
+ new_arr = []
38
+ for term in s.split("#"):
39
+ term = term.strip()
40
+ if term == "":
41
+ raise AssertionError()
42
+ if not (term.startswith("L[") and term.endswith("]")):
43
+ raise AssertionError()
44
+ li, ri = term[2:-1].split(",")
45
+ new_arr.append([int(li), int(ri)])
46
+ self.set_component_list(new_arr)
47
+
48
+ @override
49
+ def json_serialize(self) -> str:
50
+ return json.dumps({
51
+ "type": "LinkTerm",
52
+ "component_list": self.component_list
53
+ })
54
+
55
+ @override
56
+ def json_deserialize(self, s:str) -> None:
57
+ obj_now = json.loads(s)
58
+
59
+ # 控制类型
60
+ if obj_now.get("type") != "LinkTerm":
61
+ raise AssertionError()
62
+
63
+ # 必须包含完整信息
64
+ if not isinstance(obj_now.get("component_list"), list):
65
+ raise AssertionError()
66
+
67
+ # 设置元素内容
68
+ self.set_component_list(obj_now["component_list"])
69
+
70
+ if __name__ == "__main__":
71
+ var_def = LinkTerm()
72
+ var_def.set_component_list([[1, 1], [2, 1], [3, 2]])
73
+
74
+ ser = var_def.serialize()
75
+ print(ser)
76
+
77
+ new_var = LinkTerm()
78
+ new_var.deserialize("L[1, 1]#L[2, 1]#L[3, 2]")
79
+ print(new_var.json_serialize())
@@ -0,0 +1,68 @@
1
+ from typing_extensions import override
2
+ import json
3
+
4
+ try:
5
+ from .LinkRepMetaObject import LinkRepMetaObject
6
+ except:
7
+ from LinkRepMetaObject import LinkRepMetaObject
8
+
9
+ # 存储所有的变量定义
10
+ class VarDef(LinkRepMetaObject):
11
+ def __init__(self) -> None:
12
+ super().__init__()
13
+ self.var_map = dict()
14
+
15
+ # 设置变量名的映射关系
16
+ def set_var_map(self, new_var_map:dict[str, list]) -> None:
17
+ self.var_map = new_var_map
18
+
19
+ @override
20
+ def serialize(self) -> str:
21
+ return "".join([
22
+ var_name + ": " + json.dumps(self.var_map[var_name]) + "\n"
23
+ for var_name in self.var_map
24
+ ])
25
+
26
+ @override
27
+ def deserialize(self, s:str) -> None:
28
+ self.set_var_map({
29
+ item.split(":")[0].strip()
30
+ :json.loads(item.split(":")[-1])
31
+ for item in s.split("\n")
32
+ if item.find(":") != -1
33
+ })
34
+
35
+ @override
36
+ def json_serialize(self) -> str:
37
+ return json.dumps({
38
+ "type": "VarDef",
39
+ "var_map": self.var_map
40
+ })
41
+
42
+ @override
43
+ def json_deserialize(self, s:str) -> None:
44
+ obj_now = json.loads(s)
45
+
46
+ # 控制类型
47
+ if obj_now.get("type") != "VarDef":
48
+ raise AssertionError()
49
+
50
+ # 必须包含完整信息
51
+ if not isinstance(obj_now.get("var_map"), dict):
52
+ raise AssertionError()
53
+
54
+ # 设置元素内容
55
+ self.set_var_map(obj_now["var_map"])
56
+
57
+ if __name__ == "__main__":
58
+ var_def = VarDef()
59
+ var_def.set_var_map({
60
+ "L2a1": [[4, 1, 3, 2], [2, 3, 1, 4]],
61
+ "L4a1": [[6, 1, 7, 2], [8, 3, 5, 4], [2, 5, 3, 6], [4, 7, 1, 8]]
62
+ })
63
+
64
+ ser = """L2a1: [[4, 1, 3, 2], [2, 3, 1, 4]]
65
+ L4a1: [[6, 1, 7, 2], [8, 3, 5, 4], [2, 5, 3, 6], [4, 7, 1, 8]]"""
66
+
67
+ var_def.deserialize(ser)
68
+ print(var_def.json_serialize())
@@ -0,0 +1,15 @@
1
+ from .Comment import Comment
2
+ from .LinkMethod import LinkMethod
3
+ from .LinkRep import LinkRep
4
+ from .LinkSet import LinkSet
5
+ from .LinkTerm import LinkTerm
6
+ from .VarDef import VarDef
7
+
8
+ __all__ = [
9
+ "Comment",
10
+ "LinkMethod",
11
+ "LinkRep", # 其中最重要的是 LinkRep
12
+ "LinkSet",
13
+ "LinkTerm",
14
+ "VarDef"
15
+ ]
@@ -0,0 +1,18 @@
1
+ [project]
2
+ name = "link-rep"
3
+ version = "0.0.1"
4
+ description = "representation for a composite topological link."
5
+ authors = [
6
+ {name = "GGN_2015",email = "premierbob@qq.com"}
7
+ ]
8
+ license = {text = "MIT"}
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = [
12
+ "typing_extensions"
13
+ ]
14
+
15
+
16
+ [build-system]
17
+ requires = ["poetry-core>=2.0.0,<3.0.0"]
18
+ build-backend = "poetry.core.masonry.api"