A constraint is a boolean expression that specifies the relationships between various fields. The most basic form of a constraint is specified using the keyword keep. The syntax for definition of constraints is as follows:
keep constraint-bool-exp ;
A constraint is a struct member. Example 5-1 shows how a simple constraint can be specified to define relationships between fields.
Simple example of constraint definition <' struct pkt { kind: [tx, rx]; len: uint; keep kind != tx or len == 16; }; '>
Example 5-2 shows other variations of constraints. This example assumes that the fields have already been defined in a previous struct definition.
Example provides more definitions of constraints. The constraints assume that the fields in the struct my_struct have been defined previously in the original definition of the struct. The constraints simply control the generation of the fields. <' extend my_struct{ keep x > 4 and x != 6; //Can use and, or, not constructs keep x == y + 25; // Can use addition and subtraction keep z == TRUE; // z is constrained to be always true keep y == method(); // Can include method calls keep x in [5..10,20..30]; // Can constrain variable to subranges keep x not in [1..3, 5..8]; // Not in a set of subranges keep for each (p) in packets{ // Set constraint for each item in // list. p is just a placeholder. // packets is a list of structs. p.length < 10; // The length field for each packet < 10 }; keep packets.size() == 50; //Can use list pseudo-methods in calls }; '>
If two constraints contradict each other, then no value can be assigned to the field and a contradiction error is displayed.