-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve documentation for developers #116
Open
n9iels
wants to merge
6
commits into
master
Choose a base branch
from
docs/improve-documentation
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
60f9bb4
Improve README
n9iels 396dbbf
Add docs about creation of FLINT models
n9iels 7b141c1
Replace the 'reference' properties with 'sources'
n9iels 3fe9a09
Add initial documentation for expressions
n9iels 5633bad
Add examples and documentation about LIST
n9iels 3a1ef50
Add docs for CREATE and PROJECTION
n9iels File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,385 @@ | ||
# Expressions | ||
|
||
This documentation gives a in depth explanation in how to define and use expressions within FLINT models. | ||
|
||
## Usage | ||
|
||
Expressions can be used within the `preConditions` property of **acts** and the `function` property of **facts**. Within `preConditions` the expressions determines if an action can be taken by an actor. If the expressions evaluates to `false`, taking this action is not allowed. Within the `function` property of a fact, the evaluation of the expression will be the eventual value of the fact. | ||
|
||
A expression is defined by an object with the type of the expression and one or more operands. | ||
|
||
```json | ||
{ | ||
"expression": "LITERAL", | ||
"operand": "Discipl" | ||
} | ||
{ | ||
"expression": "AND", | ||
"operands": [ | ||
"[some fact]", | ||
"[another fact]" | ||
] | ||
} | ||
``` | ||
|
||
The value of a operand can be a reference to a fact, another expression or sometimes a static value. This makes them extremely powerful and gives the ability to create complex [nested expressions](#nested-expressions) with references to other facts with there own expressions. | ||
|
||
## Expressions | ||
|
||
The following paragraph lists all available expressions divided into the categories: basic; mathematical; boolean logic. | ||
|
||
### Basic | ||
|
||
#### LITERAL | ||
|
||
The `LITERAL` expression has one operand that holds a static value of a [primitive type](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values) supported by JavaScript. It is often used as fact function and can serve as operand for other expressions. | ||
|
||
> JavaScript has some natural problems with big numbers and floating points. To overcome some of this issues, numbers are handled by [big.js](https://github.com/MikeMcl/big.js/). | ||
|
||
```json | ||
{ | ||
"fact": "[aantal maanden in een jaar]", | ||
"function": { | ||
"expression": "LITERAL", | ||
"operand": 12 | ||
} | ||
} | ||
``` | ||
|
||
#### LIST | ||
|
||
The `LIST` operator can be used to collect data during evaluation of a fact. The fact containing this list can be used as input for other expressions, for example `SUM`. | ||
|
||
The `LIST` expression has a somewhat different syntax when compared to other expressions. It needs a unique `name` property for administrative purpose and a `items` property. The `items` property can be either a fact reference or another expressions. | ||
|
||
```json | ||
{ | ||
"fact": "[totale oppervlakte]", | ||
"function": { | ||
"expression": "SUM", | ||
"operands": [ | ||
{ | ||
"expression": "LIST", | ||
"name": "perceel", | ||
"items": "[oppervlakte van het perceel]" | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
#### CREATE | ||
|
||
The `CREATE` expression can be used to make sure that a fact is created as a result of an action. This prevents the usage of facts that are defined elsewhere outside the model and gives better control over the execution flow. At the same time, it is possible to enforce that other fact must exist in the context at the time of creation. Later in the program, all these facts can be referenced with the `PROJECTION` expression. | ||
|
||
```json | ||
{ | ||
"acts": [ | ||
{ | ||
"act": "<<kinderbijslag aanvragen>>", | ||
"actor": "[ouder]", | ||
"preconditions": "[bedrag]", | ||
"recipent": "[minister]", | ||
"create": [ | ||
"[aanvraag]" | ||
] | ||
} | ||
], | ||
"facts": [ | ||
{ | ||
"fact": "[aanvraag]", | ||
"function": { | ||
"expression": "CREATE", | ||
"operands": [ | ||
"[bedrag]" | ||
] | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
#### PROJECTION | ||
|
||
The `PROJECTION` expression can be used the retrieve the contents of facts defined with the `CREATE` expression. It accepts a `context` and `fact` property to define the fact that must be retrieved and the context in which it should be defined. If the fact could not be found, taking the action will fail. | ||
|
||
```json | ||
{ | ||
"acts": [ | ||
{ | ||
// Act that creates the '[aanvraag]' fact | ||
}, | ||
{ | ||
"act": "<<kinderbijslag toekennen>>", | ||
"action": "[toekennen kinderbijslag]", | ||
"actor": "[minister]", | ||
"preconditions": { | ||
"expression": "LESS_THEN", | ||
"operands": [ | ||
{ | ||
"expression": "PROJECTION", | ||
"context": [ | ||
"[aanvraag]" | ||
], | ||
"fact": "[bedrag]" | ||
}, | ||
"[maximaal bedrag]" // Fact reference to a LITERAL with a number as value | ||
] | ||
} | ||
} | ||
], | ||
"facts": [ | ||
{ | ||
"fact": "[aanvraag]", | ||
"function": { | ||
"expression": "CREATE", | ||
"operands": [ | ||
"[bedrag]" | ||
] | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
### Mathematical | ||
|
||
All expressions in this category work with literal values and can be used to perform mathematical operations. The intention for these expressions is to use them with numeric values. Other types of literals are not officially supported. | ||
|
||
#### SUM | ||
|
||
The `SUM` expression takes multiple numeric values as operands and calculates the sum. If one of the operands is `undefined`, the result of the expression will be `undefined` too. | ||
|
||
> During evaluation the [unary plus operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus) is used when non-numeric values are given as operand. An expression with 'ab' and 'cd' as operands will thus evaluate into the string 'abcd'. | ||
|
||
```json | ||
{ | ||
"fact": "[aantal kinderen]", | ||
"function": { | ||
"expression": "SUM", | ||
"operands": [ | ||
{ | ||
"expression": "LITERAL", | ||
"operand": 2 | ||
}, | ||
"[one]", // Reference to a fact with the LITERAL value 1 | ||
] | ||
} | ||
} | ||
``` | ||
|
||
#### PRODUCT | ||
|
||
The `PRODUCT` expression takes multiple numeric values as operand and returns the product of all values. If one of the operands is `undefined` , the result of the expression will be `undefined` too. | ||
|
||
> During evaluation the [multiplication operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Multiplication) is used when non-numeric values are given as operand. An expression with 'ab' and 'cd' as operands will thus evaluate into `NaN`. | ||
|
||
```json | ||
{ | ||
"fact": "[prijs inclusief btw]", | ||
"function": { | ||
"expression": "PRODUCT", | ||
"operands": [ | ||
{ | ||
"expression": "LITERAL", | ||
"operand": 100 | ||
}, | ||
"[algemeen btw tarief]" // Reference to a fact with the LITERAL value 0.21 | ||
] | ||
} | ||
} | ||
``` | ||
|
||
#### MIN | ||
|
||
The `MIN` expression takes multiple numeric values as operand and returns the smallest value. If one of the operands is `undefined` , the result of the expression will be `undefined` too. | ||
|
||
> During evaluation the [less than operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than) is used. An expression non-numeric values like 'ab' and 'cd' as operands will thus evaluate into the string 'ab'. | ||
|
||
```json | ||
{ | ||
"fact": "[laagste inkomen]", | ||
"function": { | ||
"expression": "MIN", | ||
"operands": [ | ||
{ | ||
"expression": "LITERAL", | ||
"operand": 2200 | ||
}, | ||
"[inkomen van duizend euro]" // Reference to a fact with the LITERAL value 3000 | ||
] | ||
} | ||
} | ||
``` | ||
|
||
#### MAX | ||
|
||
The `MAX` expression takes multiple numeric values as operands and returns the greatest value. If one of the operands is `undefined` , the result of the expression will be `undefined` too. | ||
|
||
> During evaluation the [greather than](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Greater_than) is used. An expression containing non-numeric values like 'ab' and 'cd' as operands will thus evaluate into the string 'cd'. | ||
|
||
```json | ||
{ | ||
"fact": "[hoogste inkomen]", | ||
"function": { | ||
"expression": "MAX", | ||
"operands": [ | ||
{ | ||
"expression": "LITERAL", | ||
"operand": 2200 | ||
}, | ||
"[inkomen van duizend euro]" // Reference to a fact with the LITERAL value 3000 | ||
] | ||
} | ||
} | ||
``` | ||
|
||
### Boolean logic | ||
|
||
Expressions in this category will evaluate into a `boolean` value. | ||
|
||
#### EQUAL | ||
|
||
The `EQUAL` expression takes multiple operands and evaluates to `true` if all operands are **strict equal** to each other. | ||
|
||
```json | ||
{ | ||
"fact": "[heeft twee kinderen]", | ||
"function": { | ||
"expression": "EQUAL", | ||
"operands": [ | ||
"[aantal kinderen]", // Reference to a fact with the LITERAL value 2 | ||
{ | ||
"expression": "LITERAL", | ||
"operand": 2 | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
#### LESS_THAN | ||
|
||
The `LESS_THAN` expression takes multiple operands evaluates `true` if the first operand is smaller than the second operand. If more than two operands are given, it evaluates to `true` if all given operands are in acceding order. | ||
|
||
> During evaluation the [less than operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than) is used. An expression containing non-numeric values like 'ab' and 'cd' as operands will thus evaluate into `true`. | ||
|
||
```json | ||
{ | ||
"fact": "[inkomen lager dan twintigduizen]", | ||
"function": { | ||
"expression": "LESS_THAN", | ||
"operands": [ | ||
"[inkomen]", // Reference to a fact with the LITERAL value 18000 | ||
{ | ||
"expression": "LITERAL", | ||
"operand": 20000 | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
#### AND | ||
|
||
The `AND` expression takes multiple operands and evaluates to `true` if none of the given operand evaluates **strict equal** to `false`. | ||
|
||
> During evaluation the [strict equality operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality) is used to check if none of the operands is `false`. An expression containing the operands `["string", 0, true]` will thus evaluate to `true` | ||
|
||
```json | ||
{ | ||
"fact": "[aan alle voorwaarden is voldaan]", | ||
"function": { | ||
"expression": "AND", | ||
"operands": [ | ||
"[heeft een tijdelijk contract]", | ||
"[ontvangt geen uitkering]" | ||
] | ||
} | ||
} | ||
``` | ||
|
||
#### OR | ||
|
||
The `OR` expression takes multiple operands and evaluates to `true` if at least one of the given operands also evaluates **strict equal** to `true`. | ||
|
||
> During evaluation the [strict equality operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality) is used to check if at least on of the facts is `true`. An expression containing the operands `["string", 0, true]` will thus evaluate to `true` | ||
|
||
```json | ||
{ | ||
"fact": "[voldoent aan tenminste een voorwaarde]", | ||
"function": { | ||
"expression": "OR", | ||
"operands": [ | ||
"[heeft een tijdelijk contract]", | ||
"[heeft geen inkomen]" | ||
] | ||
} | ||
} | ||
``` | ||
|
||
#### NOT | ||
|
||
The `NOT` expression takes one operand and evaluates to `true` if the given operand is `false` . If the given operand is not a boolean value the result of the evaluation will be `undefined`. | ||
|
||
```json | ||
{ | ||
"fact": "[woonachtig in Nederland]", | ||
"function": { | ||
"expression": "NOT", | ||
"operand": "[woonachtig in het buitenland]" | ||
} | ||
} | ||
``` | ||
|
||
## Examples | ||
|
||
### Nested expressions | ||
|
||
The true power of expressions lies in the fact that these can be nested. For example, combining the `AND`, `OR`, `NOT` expressions makes it possible to define a fact with that only evaluates to true if various conditions are me. | ||
|
||
```json | ||
{ | ||
"fact": "[leraar voldoet aan de subsidiecriteria]", | ||
"function": { | ||
"expression": "AND", | ||
"operands": [ | ||
"[leraar die bij aanvang van het studiejaar waarvoor de subsidie bestemd de graad Bachelor mag voeren]", | ||
"[leraar die op het moment van de subsidieaanvraag in dienst is bij een werkgever]", | ||
{ | ||
"expression": "OR", | ||
"operands": [ | ||
"[leraar werkt bij een of meer bekostigde onderwijsinstellingen]", | ||
"[leraar werkt in een of meer orthopedagogisch-didactische centra]" | ||
] | ||
}, | ||
{ | ||
"expression": "NOT", | ||
"operand": "[leraar is aangesteld als ambulant begeleider]" | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
Combining mathematical operations makes it possible to calculate a sum out of other calculations. | ||
|
||
```json | ||
{ | ||
"fact": "[salaris]", | ||
"function": { | ||
"expression": "SUM", | ||
"operands": [ | ||
"[bruto jaarsalaris]" | ||
{ | ||
"expression": "PRODUCT", | ||
"operands": [ | ||
"[bruto jaarsalaris]", | ||
"[wettelijk percentage vakantiebijslag]" | ||
] | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these to be filled in? If not, using jsonc as highlighting should render them nicely
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a typo here. used the retrieve