5.1. File Menu (file.rsl)

(* Chris Noe  *)
(* describe file formats *)
module File;

  from Edit import UserWorkSpace;
  from Question import QuestionDB;
  from Test import Test;

  export FileSpace, File, RequiresSaving, FileType, TakenTestType, GradedTestType;

  object FileSpace is File*
    description: (*
        A FileSpace is an abstract model of a file space in the operating
        environment in which the TestTool is run.  The FileSpace is simply
        a collection of zero or more Files, with no other properties modeled
        here.
     *);
  end;

  object File is
    components: name:FileName and permissions:FilePermissions and
        file_type:FileType and data:FileData;
    description: (*
        A File is an abstraction of a file stored in the file space.  It has a
        name, permissions, type, and data.  These are the components sufficient
        to specify the behavior of Question Tool file operations.
    *);
  end File;

  object FileName is string
    description: (*
        The name of a file.  The string representation here is an abstraction
        of file names used in specific operating environments.  Implementations
        may obey any syntactic or semantic constraints imposed by a particular
        environment.
    *);
  end;

  object FilePermissions is is_readable:IsReadable and is_writable:IsWritable
    description: (*
        FilePermissions indicate whether a file is readable and/or writable.
    *);
  end;

  object IsReadable is boolean
    description: (*
        Flag indicating whether a file is readable, which is required to be
        true by the FileOpen operation.
    *);
  end;

  object IsWritable is boolean
    description: (*
        Flag indicating whether a file is writable, which is required to be
        true by the FileSave operation.
    *);
  end;

  object FileType is test_type:TestType or taken_test_type:TakenTestType or graded_test_type:GradedTestType or other_type:OtherType
    description: (*
        The type of file data is either TestType data (which we care about)
        or any other type of data that can be stored in a file, which we don't
        care about.
    *);
  end FileType;

  object TestType
    description: (*
        File data typing tag indicating that a file contains test data
        created by the Question Tool.
    *);
  end TestType;
  
  object TakenTestType
    description: (*
        File data typing tag indicating that a file contains taken test data
        created by the Question Tool.
    *);
  end TakenTestType;
  
  object GradedTestType
    description: (*
        File data typing tag indicating that a file contains graded test data
        created by the Question Tool.
    *);
  end GradedTestType;

  object OtherType
    description: (*
        File data typing tag indicating that a file contains data other than
        test data created by the Question Tool.
    *);
  end OtherType;

  object FileData is Test
    description: (*
        The abstract representation of test-type FileData is a Test
        object.  Question Tool implementors may use any concrete file data
        representation that accurately holds all Test components.
    *);
  end FileData;

  object RequiresSaving is boolean
    description: (*
        True if a test requires saving, which is the case if one or more
        successful edit operations has been performed since the
        most recent save.  
    *);
  end RequiresSaving;

  operation FileNew is
    inputs: uws:UserWorkSpace;
    outputs: uws':UserWorkSpace;

    description: (*
        Add a new empty test to the workspace and make it current.
    *);

    precondition: (* none *);

    postcondition:
        (*
         * The output workspace has a new empty test and that test is
         * current.  We are using a single document model, so the logic
	 * here is fairly simple.
         *)
        (exists (test:Test)
            (test = uws'.test) and
            (not test.requires_saving)
        );

  end FileNew;

  operation FileOpen is
    inputs: fs:FileSpace, fn:FileName, uws:UserWorkSpace;
    outputs: uws':UserWorkSpace;

    description: (*
        Open an existing test file of the given name and put the data from
        that file in the workspace.
    *);

    precondition:
        (*
         * A file of the given name exists in the given file space, the file
         * is readable, and the file's data are of type test.
         *)
        exists (file in fs)
            (file.name = fn) and
            file.permissions.is_readable and
            file.file_type?test_type;

    postcondition:
        (*
         * The output workspace has a new test containing the file data of
         * the input file. We are using a single document model.
         *)
        (exists (test:Test)
            (test = uws'.test) and
            (exists (file in fs)
                (file.name = fn) and
                (test = file.data)
            ) and
            (not test.requires_saving)
        );

  end FileOpen;

  operation FileClose is
    inputs: fs:FileSpace, uws:UserWorkSpace;
    outputs: uws':UserWorkSpace;

    description: (*
        Close the current test if it does not require saving.
    *);

    precondition:
        (*
         * The test does not require saving.
         *)
        not (uws.test.requires_saving);

    postcondition:
        (*
         * The current test is deleted from the workspace.  
         *)
        (uws.test = nil);

  end FileClose;

operation FileSave is
    inputs: fs:FileSpace, uws:UserWorkSpace;
    outputs: fs':FileSpace, uws':UserWorkSpace;

    description: (*
        If the test in the given workspace requires saving, save it in the
        given file space.
    *);

    precondition:
        (*
         * The given workspace requires saving.  Also, there is a writable
         * file of the current workspace filename in the given FileSpace.  Note
         * that the only way the current file could be unwritable is through an
         * external change to the file space since the file was opened by the
         * Question Tool.  Note further that this precondition disallows the
         * case where the current test file has been externally deleted
         * since it was opened by the test tool.  That is, the file must
         * both exist and be writable at the time the save is attempted.
         *)
        (uws.test.requires_saving)

            and

        (exists (file in fs)
            (file.name = uws.test.file.name) and
            (file.permissions.is_writable));

    postcondition:
        (*
         * There is a test-type file in the resulting FileSpace containing
         * the current workspace test as its file data.  In the resulting
         * workspace, the requires saving indicator is false.
         *)
        (exists (file in fs')
            (file.name = uws'.test.file.name) and
            (file.data = uws'.test) and
            (file.permissions.is_writable) and
            (file.file_type?test_type) and
            (not uws'.test.requires_saving)
        );
  end FileSave;
end File;

Prev: none | Next: edit.rsl | Up: formal specification | Top: index