-
-
Notifications
You must be signed in to change notification settings - Fork 11
The Bank Example (Advanced Role features)
Max Leuthaeuser edited this page May 10, 2026
·
4 revisions
This page shows some more advanced role-features within the bank example.
┏━━━━━━━━━━━━━━━━━━┓
┃ Transaction ┃
┣━━━━━━━━━━━━━━━━━━┫
┃ (2..2) ┃
┃╭┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╮┃
┃┆ (1..1) ┆┃
┃┆╭──────────────╮┆┃
┃┆│ Source │┆┃
┃┆╰──────────────╯┆┃ Role-Group Participants
┃┆╭──────────────╮┆┃ (an account cannot play both
┃┆│ Target │┆┃ roles at the same time
┃┆╰──────────────╯┆┃ in the same transaction!)
┃╰┄┄┄┄┄┄┄▲┄┄┄┄┄┄┄┄╯┃
┗━━━━━━━━┿━━━━━━━━━┛
┏━━━━┷━━━━┓
┃ Account ┃
┗━━━━━━━━━┛
You may check your role-binding statements like this:
val aAccount = new Account(10)
new Transaction(10) {
RoleGroup("Participants").containing[Source, Target](1, 1)(2, 2)
RoleGroupsChecked {
aAccount play new Source
aAccount play new Target
}
}Executing this code results in:
scroll.internal.errors.SCROLLErrors$RoleGroupInnerCardinalityViolation:
Constraint set for inner cardinality of role group 'Participants' violated!
The following modification fixes the constraint violation like expected:
val aAccount = new Account(10)
val anotherAccount = new Account(0)
new Transaction(10) {
RoleGroup("Participants").containing[Source, Target](1, 1)(2, 2)
RoleGroupsChecked {
aAccount play new Source
anotherAccount play new Target
}
}┏━━━━━━━━━━━━━━━━┓
┃ Transaction ┃
┣━━━━━━━━━━━━━━━━┫
┃╭──────────────╮┃
┃│ Source │┃
┃╰──▲───────────╯┃
┃ │ ┯ ┃
┃ │ │ ┃ Role-Prohibition
┃ │ ┷ ┃ (semantically equivalent to
┃╭──┼───────────╮┃ the Role-Group shown already)
┃│ │ Target │┃
┃╰──┼────────▲──╯┃
┗━━━┿━━━━━━━━┿━━━┛
┏┷━━━━━━━━┷┓
┃ Account ┃
┗━━━━━━━━━━┛
You may check your role-binding statements like this:
val aAccount = new Account(10)
new Transaction(10) {
RoleProhibition[Source, Target]
RoleConstraintsChecked {
aAccount play new Source
aAccount play new Target
}
}Executing this code results in:
scroll.internal.errors.SCROLLErrors$RoleProhibitionConstraintViolation:
Role prohibition constraint violation: 'Account@53a7646' plays role 'Transaction$Target', but it is not allowed to do so!
The following modification fixes the constraint violation like expected:
val aAccount = new Account(10)
val anotherAccount = new Account(0)
new Transaction(10) {
RoleProhibition[Source, Target]
RoleConstraintsChecked {
aAccount play new Source
anotherAccount play new Target
}
}┏━━━━━━━━━━━━━━━━━━┓
┃ Transaction ┃
┣━━━━━━━━━━━━━━━━━━┫
┃ (2..2) ┃
┃╭┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╮┃
┃┆ (1..1) ┆┃
┃┆╭──────────────╮┆┃
┃┆│ Source │┆┃
┃┆╰────┬─────────╯┆┃
┃┆ 1│ ┆┃
┃┆ │ transfer ┆┃ Role-Relationship
┃┆ 1│ ┆┃
┃┆╭────┴─────────╮┆┃
┃┆│ Target │┆┃
┃┆╰──────────────╯┆┃
┃╰┄┄┄┄┄┄┄▲┄┄┄┄┄┄┄┄╯┃
┗━━━━━━━━┿━━━━━━━━━┛
┏━━━━┷━━━━┓
┃ Account ┃
┗━━━━━━━━━┛
You can define relationships like this:
val aAccount = new Account(10)
val anotherAccount = new Account(0)
new Transaction(10) {
aAccount play new Source
anotherAccount play new Target
val r = Relationship("transfer").from[Source](1).to[Target](1)
println("Left side: " + r.left())
println("Right side: " + r.right())
}Execution this code would print:
Left side: ArrayBuffer(Transaction$Source@30612fa6)
Right side: ArrayBuffer(Transaction$Target@16cef1cf)
The following code violates the relationship cardinalities specified:
val aAccount = new Account(10)
val anotherAccount = new Account(0)
val aThirdAccount = new Account(0)
new Transaction(10) {
aAccount play new Source
anotherAccount play new Target
aThirdAccount play new Target
val r = Relationship("transfer").from[Source](1).to[Target](1)
println("Left side: " + r.left())
println("Right side: " + r.right())
}Executing this would print:
Left side: ArrayBuffer(Transaction$Source@54970d40)
scroll.internal.errors.SCROLLErrors$ConcreteRelationshipMultiplicityViolation:
With a concrete multiplicity for 'transfer' of '1' the resulting role set should have the same size!