add two more tutorials
This commit is contained in:
parent
1dfeef767e
commit
069cb439cb
2 changed files with 156 additions and 0 deletions
92
tutorial/01_constraints.py
Normal file
92
tutorial/01_constraints.py
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
# We now make our meta-model more interesting by adding a 'price' attribute to B, and constraints to it.
|
||||||
|
|
||||||
|
mm_cs = """
|
||||||
|
# class named 'A':
|
||||||
|
A:Class
|
||||||
|
|
||||||
|
# class named 'B':
|
||||||
|
B:Class {
|
||||||
|
constraint = ```
|
||||||
|
# Price must be less than 100
|
||||||
|
get_value(get_slot(this, "price")) < 100
|
||||||
|
```;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 'B' has an attribute 'price':
|
||||||
|
B_price:AttributeLink (B -> Integer) {
|
||||||
|
name = "price";
|
||||||
|
optional = False;
|
||||||
|
}
|
||||||
|
|
||||||
|
# An association from 'A' to 'B':
|
||||||
|
a2b:Association (A -> B) {
|
||||||
|
# Every 'A' must be associated with at least one 'B'
|
||||||
|
target_lower_cardinality = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalPriceLessThan500:GlobalConstraint {
|
||||||
|
constraint = ```
|
||||||
|
total_price = 0;
|
||||||
|
for b_name, b_id in get_all_instances("B"):
|
||||||
|
total_price += get_value(get_slot(b_id, "price"))
|
||||||
|
total_price < 500
|
||||||
|
```;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
####
|
||||||
|
# Note: The name 'B_price' follows a fixed format: <class_name>_<attribute_name>.
|
||||||
|
# This format must be followed!
|
||||||
|
####
|
||||||
|
|
||||||
|
# We update our model to include a price:
|
||||||
|
|
||||||
|
m_cs = """
|
||||||
|
myA:A
|
||||||
|
|
||||||
|
myB:B {
|
||||||
|
price = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
myLnk:a2b (myA -> myB)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# And do a conformance check:
|
||||||
|
|
||||||
|
from state.devstate import DevState
|
||||||
|
from bootstrap.scd import bootstrap_scd
|
||||||
|
from concrete_syntax.textual_od import parser
|
||||||
|
from framework.conformance import Conformance, render_conformance_check_result
|
||||||
|
|
||||||
|
state = DevState()
|
||||||
|
print("Loading meta-meta-model...")
|
||||||
|
mmm = bootstrap_scd(state)
|
||||||
|
print("OK")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("Parsing meta-model...")
|
||||||
|
mm = parser.parse_od(
|
||||||
|
state,
|
||||||
|
m_text=mm_cs, # the string of text to parse
|
||||||
|
mm=mmm, # the meta-model of class diagrams (= our meta-meta-model)
|
||||||
|
)
|
||||||
|
print("OK")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("Parsing model...")
|
||||||
|
m = parser.parse_od(
|
||||||
|
state,
|
||||||
|
m_text=m_cs,
|
||||||
|
mm=mm, # this time, the meta-model is the previous model we parsed
|
||||||
|
)
|
||||||
|
print("OK")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("Is our model a valid instance of our meta model?")
|
||||||
|
conf = Conformance(state, m, mm)
|
||||||
|
print(render_conformance_check_result(conf.check_nominal()))
|
||||||
|
|
||||||
|
# Can you fix the constraint violation?
|
||||||
|
|
||||||
|
|
||||||
64
tutorial/02_inheritance.py
Normal file
64
tutorial/02_inheritance.py
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
|
||||||
|
# The following meta-model has an inheritance relation:
|
||||||
|
|
||||||
|
mm_cs = """
|
||||||
|
MyAbstractClass:Class {
|
||||||
|
abstract = True;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyConcreteClass:Class
|
||||||
|
|
||||||
|
:Inheritance (MyConcreteClass -> MyAbstractClass)
|
||||||
|
|
||||||
|
Z:Class
|
||||||
|
|
||||||
|
myZ:Association (MyAbstractClass -> Z) {
|
||||||
|
target_lower_cardinality = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Note that we didn't give our inheritance link a name. A unique name will be auto-generated by the parser.
|
||||||
|
|
||||||
|
|
||||||
|
# A (non-conforming) instance:
|
||||||
|
|
||||||
|
m_nonconform_cs = """
|
||||||
|
cc:MyConcreteClass
|
||||||
|
z:Z
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# Check conformance:
|
||||||
|
|
||||||
|
from state.devstate import DevState
|
||||||
|
from bootstrap.scd import bootstrap_scd
|
||||||
|
# from concrete_syntax.textual_od import parser
|
||||||
|
# from framework.conformance import Conformance, render_conformance_check_result
|
||||||
|
from util import loader
|
||||||
|
|
||||||
|
state = DevState()
|
||||||
|
mmm = bootstrap_scd(state)
|
||||||
|
|
||||||
|
mm = loader.parse_and_check(state, mm_cs, mmm, "mm")
|
||||||
|
|
||||||
|
print("should be non-conform:")
|
||||||
|
m_nonconform = loader.parse_and_check(state, m_nonconform_cs, mm, "m_nonconform")
|
||||||
|
|
||||||
|
|
||||||
|
# The reason for the non-conformance is that all cardinalities and constraints are inherited. Therefore 'MyConcreteClass' must have at least one outgoing 'myZ' link as well.
|
||||||
|
|
||||||
|
# We fix the non-conformance by adding this link:
|
||||||
|
|
||||||
|
m_conform_cs = m_nonconform_cs + """
|
||||||
|
:myZ (cc -> z)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Now everything will be fine
|
||||||
|
|
||||||
|
print("should be conform:")
|
||||||
|
m_conform = loader.parse_and_check(state, m_conform_cs, mm, "m_conform")
|
||||||
|
print("OK")
|
||||||
|
|
||||||
|
|
||||||
|
# On to the next tutorial...
|
||||||
Loading…
Add table
Add a link
Reference in a new issue