diff options
Diffstat (limited to 'subprojects/docs/src/learn/tutorials/file-system/index.md')
-rw-r--r-- | subprojects/docs/src/learn/tutorials/file-system/index.md | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/subprojects/docs/src/learn/tutorials/file-system/index.md b/subprojects/docs/src/learn/tutorials/file-system/index.md new file mode 100644 index 00000000..365d0fba --- /dev/null +++ b/subprojects/docs/src/learn/tutorials/file-system/index.md | |||
@@ -0,0 +1,209 @@ | |||
1 | --- | ||
2 | SPDX-FileCopyrightText: 2023-2024 The Refinery Authors | ||
3 | SPDX-License-Identifier: EPL-2.0 | ||
4 | description: Introduction to classes, references, and error predicates | ||
5 | sidebar_position: 0 | ||
6 | sidebar_label: File system | ||
7 | --- | ||
8 | |||
9 | # File system tutorial | ||
10 | |||
11 | The goal of this tutorial is to give a brief overview of the partial modeling and model generation features of the Refinery framework. The running example will be the modeling of files, directories, and repositories. | ||
12 | |||
13 | ## Partial models | ||
14 | |||
15 | ### Types and relations | ||
16 | |||
17 | - First, let us introduce some basic types: `Dir`, `File`, and `FileSystem`, along with the relations between them: `element` and `root`. There is a `scope` expression at the end, which we will ignore for now. | ||
18 | |||
19 | ```refinery | ||
20 | class FileSystem { | ||
21 | contains File[1] root | ||
22 | } | ||
23 | |||
24 | class File. | ||
25 | |||
26 | class Dir extends File { | ||
27 | contains File[] element | ||
28 | } | ||
29 | |||
30 | scope node = 10. | ||
31 | ``` | ||
32 | |||
33 | import Link from '@docusaurus/Link'; | ||
34 | |||
35 | <p> | ||
36 | <Link | ||
37 | href="https://refinery.services/#/1/KLUv_SDT_QMAQkcXGnBL2-ikxOa10ZNeN1bwnxijfsojpwHQAxAE5pzBk5uCd8F5EjAGJrUNQBWIbdRU7tkRB-VsG_aVuMlSEWzzTShXE8h-eBHzK_cK11NoD9P_2_GFrS61RRmuipYUCwA046ljtvEqgDAGQyDQwsIqKACEt2LiANXAaUxBAQ==" | ||
38 | className="button button--lg button--primary button--play" | ||
39 | >Try in Refinery</Link> | ||
40 | </p> | ||
41 | |||
42 | - Notice that the syntax is essentially identical to [Xcore](https://wiki.eclipse.org/Xcore). | ||
43 | - Review the partial model visualization. You should get something like this: | ||
44 | |||
45 | import Fig1 from './fig1.svg'; | ||
46 | |||
47 | <Fig1 title="Initial model" /> | ||
48 | |||
49 | - Add some statements about a partial model: | ||
50 | |||
51 | ```refinery | ||
52 | class FileSystem { | ||
53 | contains File[1] root | ||
54 | } | ||
55 | |||
56 | class File. | ||
57 | |||
58 | class Dir extends File { | ||
59 | contains File[] element | ||
60 | } | ||
61 | |||
62 | Dir(resources). | ||
63 | element(resources, img). | ||
64 | File(img). | ||
65 | |||
66 | scope node = 10. | ||
67 | ``` | ||
68 | |||
69 | import Fig2 from './fig2.svg'; | ||
70 | |||
71 | <Fig2 title="Partial model extended with new facts" /> | ||
72 | |||
73 | ### Partial models | ||
74 | |||
75 | - Notice that the instance model elements are coexisting with ```<type>::new``` nodes representing the prototypes of newly created objects. | ||
76 | |||
77 | - Check the disabled `equals` and `exist` predicates. check the visual annotation of those predicates in the visualization (dashed line, shadow). | ||
78 | |||
79 | import Fig3 from './fig3.svg'; | ||
80 | |||
81 | <Fig3 title="Object existence and equality" /> | ||
82 | |||
83 | ### Information merging | ||
84 | |||
85 | - For the object `img`, we didn't specify if it is a directory or not. Therefore, it will typically be a folder. | ||
86 | |||
87 | - If we want to state that img is not a directory, we need to a negative statement: | ||
88 | |||
89 | ```refinery | ||
90 | !Dir(img). | ||
91 | ``` | ||
92 | |||
93 | - Statements are merged with respect to the refinement relation of 4-valued logic. | ||
94 | |||
95 | - If we add, a statement both negatively and positively, it will create an inconsistency: | ||
96 | |||
97 | ```refinery | ||
98 | element(resources, img). | ||
99 | !element(resources, img). | ||
100 | ``` | ||
101 | |||
102 | - Inconsistent models parts in a partial model typically make the problem trivially unsatisfiable. | ||
103 | |||
104 | import Fig4 from './fig4.svg'; | ||
105 | |||
106 | <Fig4 title="Inconsistent partial model" /> | ||
107 | |||
108 | - However, the model can be saved if the inconsistent part may not exist... | ||
109 | |||
110 | ```refinery | ||
111 | !File(File::new). | ||
112 | ``` | ||
113 | |||
114 | ### Default values | ||
115 | |||
116 | - A large amount of statements can be expressed by using `*`. | ||
117 | - The `default` keyword defines lower priority statements that need to be considered unless other statement specifies otherwise. No information merging is happening. | ||
118 | |||
119 | ## Constraints | ||
120 | |||
121 | Let's extend the metamodel with a new class `SymLink`: | ||
122 | |||
123 | ```refinery | ||
124 | class FileSystem { | ||
125 | contains File[1] root | ||
126 | } | ||
127 | |||
128 | class File. | ||
129 | |||
130 | class Dir extends File { | ||
131 | contains File[0..10] element | ||
132 | } | ||
133 | |||
134 | class SymLink extends File { | ||
135 | File[1] target | ||
136 | } | ||
137 | |||
138 | Dir(resources). | ||
139 | element(resources, img). | ||
140 | element(resources, link). | ||
141 | target(link, img). | ||
142 | |||
143 | scope node = 10. | ||
144 | ``` | ||
145 | |||
146 | - Add some simple constraints: | ||
147 | |||
148 | ```refinery | ||
149 | % Simple constraints: | ||
150 | pred hasReference(f) <-> target(_, f). | ||
151 | error pred selfLoop(s) <-> target(s, s). | ||
152 | target(x,x). | ||
153 | ``` | ||
154 | |||
155 | - There are no empty directories in a git repository, so let's forbid them! | ||
156 | |||
157 | ```refinery | ||
158 | error pred emptyDir(d) <-> Dir(d), !element(d,_). | ||
159 | ``` | ||
160 | |||
161 | - End result: | ||
162 | |||
163 | ```refinery | ||
164 | class FileSystem { | ||
165 | contains File[1] root | ||
166 | } | ||
167 | |||
168 | class File. | ||
169 | |||
170 | class Dir extends File { | ||
171 | contains File[0..10] element | ||
172 | } | ||
173 | |||
174 | class SymLink extends File { | ||
175 | File[1] target | ||
176 | } | ||
177 | |||
178 | Dir(resources). | ||
179 | element(resources, img). | ||
180 | !Dir(img). | ||
181 | element(resources, link). | ||
182 | target(link,img). | ||
183 | |||
184 | % Simple constraints: | ||
185 | pred hasReference(f) <-> target(_, f). | ||
186 | error pred selfLoop(s) <-> target(s, s). | ||
187 | |||
188 | % Object equality with ==: | ||
189 | error pred emptyDir(d) <-> Dir(d), !element(d, _). | ||
190 | pred importantFile(f) <-> target(l1, f), target(l2, f), l1 != l2. | ||
191 | |||
192 | % Transitive closure, and | ||
193 | pred containsFile(fs, file) <-> | ||
194 | FileSystem(fs), | ||
195 | root(fs, file) | ||
196 | ; | ||
197 | FileSystem(fs), | ||
198 | root(fs, rootDir), | ||
199 | element+(rootDir, file). | ||
200 | |||
201 | % Predicate reuse | ||
202 | error conflictBetweenTwoFileSystem(fs1, fs2, l, t) <-> | ||
203 | containsFile(fs1, l), | ||
204 | containsFile(fs2, t), | ||
205 | fs1 != fs2, | ||
206 | target(l, t). | ||
207 | |||
208 | scope node = 40..50, FileSystem = 2, importantFile = 1..*. | ||
209 | ``` | ||