aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/docs/src/learn/tutorials/file-system/index.md
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/docs/src/learn/tutorials/file-system/index.md')
-rw-r--r--subprojects/docs/src/learn/tutorials/file-system/index.md209
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---
2SPDX-FileCopyrightText: 2023-2024 The Refinery Authors
3SPDX-License-Identifier: EPL-2.0
4description: Introduction to classes, references, and error predicates
5sidebar_position: 0
6sidebar_label: File system
7---
8
9# File system tutorial
10
11The 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
20class FileSystem {
21 contains File[1] root
22}
23
24class File.
25
26class Dir extends File {
27 contains File[] element
28}
29
30scope node = 10.
31```
32
33import 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
45import Fig1 from './fig1.svg';
46
47<Fig1 title="Initial model" />
48
49- Add some statements about a partial model:
50
51```refinery
52class FileSystem {
53 contains File[1] root
54}
55
56class File.
57
58class Dir extends File {
59 contains File[] element
60}
61
62Dir(resources).
63element(resources, img).
64File(img).
65
66scope node = 10.
67```
68
69import 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
79import 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
98element(resources, img).
99!element(resources, img).
100```
101
102- Inconsistent models parts in a partial model typically make the problem trivially unsatisfiable.
103
104import 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
121Let's extend the metamodel with a new class `SymLink`:
122
123```refinery
124class FileSystem {
125 contains File[1] root
126}
127
128class File.
129
130class Dir extends File {
131 contains File[0..10] element
132}
133
134class SymLink extends File {
135 File[1] target
136}
137
138Dir(resources).
139element(resources, img).
140element(resources, link).
141target(link, img).
142
143scope node = 10.
144```
145
146- Add some simple constraints:
147
148```refinery
149% Simple constraints:
150pred hasReference(f) <-> target(_, f).
151error pred selfLoop(s) <-> target(s, s).
152target(x,x).
153```
154
155- There are no empty directories in a git repository, so let's forbid them!
156
157```refinery
158error pred emptyDir(d) <-> Dir(d), !element(d,_).
159```
160
161- End result:
162
163```refinery
164class FileSystem {
165 contains File[1] root
166}
167
168class File.
169
170class Dir extends File {
171 contains File[0..10] element
172}
173
174class SymLink extends File {
175 File[1] target
176}
177
178Dir(resources).
179element(resources, img).
180!Dir(img).
181element(resources, link).
182target(link,img).
183
184% Simple constraints:
185pred hasReference(f) <-> target(_, f).
186error pred selfLoop(s) <-> target(s, s).
187
188% Object equality with ==:
189error pred emptyDir(d) <-> Dir(d), !element(d, _).
190pred importantFile(f) <-> target(l1, f), target(l2, f), l1 != l2.
191
192% Transitive closure, and
193pred 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
202error conflictBetweenTwoFileSystem(fs1, fs2, l, t) <->
203 containsFile(fs1, l),
204 containsFile(fs2, t),
205 fs1 != fs2,
206 target(l, t).
207
208scope node = 40..50, FileSystem = 2, importantFile = 1..*.
209```