0

How can the following constraints be expressed:

1 - There is exactly one folder that is not a sub-directory to another directory. (I couldn't fully understand the folder/subfolder theme and how to describe the only one possible exclusion from the folder system)

And there are also some question which comes from the first question

2 The highest nesting of folders does not exceed the number n.

3) The total number of files on your system can not exceed the number n.

4) The total number of files (subdirectory) in a given system cannot exceed the number n.

The uml diagram

bruno
  • 32,421
  • 7
  • 25
  • 37
HollySeater
  • 25
  • 1
  • 7
  • What is your question? – qwerty_so Jan 20 '21 at 09:16
  • Oh, sorry. Edited. I should define in UML the listed constraints – HollySeater Jan 20 '21 at 09:25
  • probably *a sub-directory **to** another directory* means *a sub-directory **of** another directory* . What is the goal of `(subdirectory)` in 4 ? Why in 1 and 2 there is no reference to the system but in 3 and 4 it is *your system* and *a given system* ? The statement is not clear at all, I can only say you to use *constraints* typically in OCL for these requirements, but I cannot help more while the statement is not clear – bruno Jan 20 '21 at 10:30
  • I still don't see the question. The constraints are defined already. – qwerty_so Jan 20 '21 at 11:50
  • Are you looking for OCL constraints maybe? Most of these constraints can't be expressed using simple multiplicities of associations. – Geert Bellekens Jan 20 '21 at 12:04
  • Thank all of you, guys – HollySeater Jan 21 '21 at 13:17

2 Answers2

2

Your four constraints cannot be expressed simply using the multiplicities.

In UML theses constraints can be written using OCL, see formal/2014-02-03

Of course the constraints can be written in a class diagram, for instance see figure 7.14 Constraint in a note symbol page 37 of formal/2017-12-05.

1 - There is exactly one folder that is not a sub-directory to another directory

one way to write that is :

Folder.allInstances()->select(f | f.upfolder->isEmpty())->size() = 1

where

  • Folder.allInstances() return the instances of the class Folder
  • Folder.allInstances()->select(f | f.upfolder->isEmpty()) iterate on the instances and return the instances having no upfolder
  • Folder.allInstances()->select(f | f.upfolder->isEmpty())->size() = 1 then checks there is one folder without upfolder

2 The highest nesting of folders does not exceed the number n

one way is to define a function computing the depth of a folder then to check all the folder have a depth less or equals to n

context Folder
def: depth() : Integer =
  if upfolder->notEmpty() then
    upfolder->first().depth() + 1
  else
    0

Folder.allInstances()->forAll(f | f.depth() <= n)

where forAll is true if the condition depth() <= n is true for all the elements

But it is only useful to compute the depth of the folders without sub folder, so

Folder.allInstances()
  ->select(f | f.subfolder->isEmpty())
     ->forAll(f | f.depth() <= n)

3) The total number of files on your system can not exceed the number n.

4) The total number of files (subdirectory) in a given system cannot exceed the number n.

I do not understand why (subdirectory) in 4 nor why 3 says on your system and 4 says a given system while there is nothing about system in 1 and 2.

Supposing the goal is to check the total number of files is less or equals to n and the files of a folder are given by the attribute file :

Folder.allInstances()->collect(f | f.file.size()).sum() <= n

where

  • Folder.allInstances()->collect(f | f.file.size()) returns the collection of the number of files for all the folders
  • Folder.allInstances()->collect(f | f.file.size()).sum() return the total number of files
bruno
  • 32,421
  • 7
  • 25
  • 37
0

The use of allInstances() is discouraged.

  1. It is very desirable to have some FileSystem class that has exactly one root Folder, therefore guaranteeing the constraint in a simple multiplicity.

  2. Is easily handled by a [0..3] multiplicity declaration.

  3. A depth() helper helpfully cached by a derived property is a good solution.

Or just: context File inv: Folder->closure(upFolder).size() < n

  1. context Folder inv: self->closure(subfolder).File->size() < n
Ed Willink
  • 1,205
  • 7
  • 8
  • `The use of allInstances() is discouraged` : by who ? from where you get that ? why, for performance reasons ? OCL is very far of concept of performances. Out of that in the statement does not give a way to access the instances so no other choice – bruno Jan 25 '21 at 09:36
  • `1. It is very desirable to have ...` : for sure to have the root(s) of the filesystem is the right way ... but nothing about that in the statement, so have to do in an other way – bruno Jan 25 '21 at 09:37
  • `2. Is easily handled by a [0..3] multiplicity declaration` : multiplicity on what ? why 0..3 ? and how a multiplicities can handle the depth of a folder ? – bruno Jan 25 '21 at 09:38
  • `3. A depth() helper helpfully cached by a derived property is a good solution.` : first the depth is for `2.`rather than `3.`, and for sure if we don't have to compute the depth it is better, but first that does not exist in the statement, second that must be update each time a folder must be moved, and third notice that information does not exist in 'standard' file system. So I indicate a way to compute it – bruno Jan 25 '21 at 09:43
  • `3. context Folder inv: self->closure(subfolder).File->size() < n`: out of my doubt about closure (this is why I do not used it) the question is about the system, so only interesting when *self* is the (non directly available) root of the file system. Of course if this is true for any folder it is also for the root(s) – bruno Jan 25 '21 at 09:54