Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 56 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Assert
======

A simple assertion utility taking advantage of the Fortran 2018 standard's introduction of variable stop codes and error termination inside pure procedures.
A simple assertion utility taking advantage of the Fortran 2018 standard's introduction of variable stop codes
and error termination inside pure procedures.

Motivations
-----------
Expand All @@ -10,22 +11,68 @@ Motivations

Overview
--------
This assertion utility contains just one public procedure: an `assert` subroutine that
This assertion utility contains one public procedure and one public abstract type: `assert` and `characterizable_t`, respectively.
The `assert` subroutine

1. error-terminates with a variable stop code when a user-defined logical assertion fails,
2. includes user-supplied diagnostic data in the output if provided by the calling procedure,
3. is callable inside `pure` procedures, and
4. can be eliminated by an optimizing compiler through the use of a preprocessor macro: `-DUSE_ASSERTIONS=.false.`.
4. can be eliminated during an optimizing compiler's dead-code removal phase based on a preprocessor macro: `-DUSE_ASSERTIONS=.false.`.

The intended uses cases are twofold: (1) enforcing programming contracts throughout a project
and (2) providing a convenient way to get temporarily produce output for debugging purposes.o
The `characterizable_t` abstract derived type provides a mechanism for obtaining diagnostic data from a user-defined derived type that implements the `characterizable_t`'s `as_character()` deferred binding.

Contracts enforce
Use Cases
---------
1. [Enforcing programming contracts] throughout a project via runtime checks.
2. Produce output in `pure` procedures for debugging purposes.

### Enforcing programming contracts

1. Preconditions (requirements): `logical` expressions that must evaluate to `.true.` when a procedure starts execution,
2. Postconditions (assurances): expressions that must evaluate to `.false.`
3. Invariants: universal pre- and postconditions that must always be true when all procedures in a class or package start or finish executing.

Examples
--------
See [./examples](./examples).
### Examples
See the [./example](./example) subdirectory.

Downloading, Building, and Running Examples
-------------------------------------------
Prerequisites:
1. A Fortran 2018 compiler (recent Cray, Intel, GNU, and NAG compiler versions suffice).
2. The [Fortran Package Manager](https://github.com/fortran-lang/fpm).
3. _Optional_: [OpenCoarrays] for parallel execution with the GNU Fortran compiler.

### Single-image execution
```
git clone git@github.com:sourceryinstitute/assert
cd assert
fpm run --example simple_assertions
fpm run --example derived_type_diagnostic
```
where the `fpm run` automatically invokes `fpm build` if necessary, .e.g., the `fpm` source has
changed since the most recent build. If `assert` is working correctly, the first `fpm run` above
will error-terminate with the character stop code
```
Assertion "x > 0" failed on image 1 with diagnostic data "-1.00000000"
```
and the second `fpm run` above will error-terminate with the character stop code
```
Assertion "stuff_t%z(): self%defined()" failed on image 1 with diagnostic data "(none provided)"
```

### Multi-image execution with `gfortran` and OpenCoarrays
```
git clone git@github.com/sourceryinstitute/assert
cd assert
fpm run --compiler caf --runner "cafrun -n 2" --example simple_assertions
fpm run --compiler caf --runner "cafrun -n 2" --example derived_type_diagnostic
```
Replace either instance of `2` above with the desired number of images to run for parallel execution.
If `assert` is working correctly, both of the latter `fpm run` commands will error-terminate with one
or more images providing stop codes analogous to those quoted in the [Single-image execution] section.

[Hyperlinks]:#
[OpenCoarrays]: https://github.com/sourceryinstitute/opencoarrays
[Enforcing programming contracts]: #enforcing-programming-contracts
[Single-image execution]: #single-image-execution

1 change: 1 addition & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
![Classes involved in [derived_type_diagnostic.f90](./derived_type_diagnostic.f90)](https://user-images.githubusercontent.com/13108868/130385757-6b79e5f1-5dec-440c-98f5-0f659c538754.png)