Now we will learn a "real world" example written in Chomik. Study the below code. Notice that some informations depend on other informations (recursive enumerations!). Also some actions depend on other actions.
let amount of places=value integer 5;
let amount of persons=value integer 3;
let amount of keys = value integer 5;
type person_id = 1..<amount of persons>;
type place_id = 1..<amount of places>;
type key_id = 1..<amount of keys>;
type race={human,dwarf,elf};
type class={warrior,wizard,cleric};
type feature={strength,dexterity,magic};
type place_type={house,tower,prison,inn};
type information={
none,
person (A:person_id) can see person (B:person_id),
person (A:person_id) has class (C:class),
person (A:person_id) has race (R:race),
person (A:person_id) is in place (B:place_id),
person (A:person_id) has key (B:key_id),
person (A:person_id) has the key opening place (B:place_id),
person (A:person_id) has told person (B:person_id) that (I:information) is (V:boolean),
person (A:person_id) has asked person (B:person_id) whether (I:information) is (V:boolean),
person (A:person_id) has attacked person (B:person_id),
person (A:person_id) thinks that (I:information) is (V:boolean),
place (A:place_id) is a (B:place_type),
key (A:key_id) can open place (B:place_id)
};
type action={
wait,
tell person (A:person_id) that (I:information) is (V:boolean),
ask person (A:person_id) whether (I:information) is (V:boolean),
give person (A:person_id) the key (K:key_id),
go to place (A:place_id),
ask person (A:person_id) to (B:action),
attack person (A:person_id),
pick up the key (K:key_id)
};
expand(2);
<print (I:information)>;
person3thinksthatperson1hasthekeyopeningplace1isfalse person3thinksthatperson1hasthekeyopeningplace1istrue person3thinksthatperson1hasthekeyopeningplace2isfalse person3thinksthatperson1hasthekeyopeningplace2istrue person3thinksthatperson1hasthekeyopeningplace3isfalse person3thinksthatperson1hasthekeyopeningplace3istrue person3thinksthatperson1hasthekeyopeningplace4isfalse person3thinksthatperson1hasthekeyopeningplace4istrue person3thinksthatperson1hasthekeyopeningplace5isfalse person3thinksthatperson1hasthekeyopeningplace5istrue
Chomik provides a way to parse the signatures of such kind using something similar to the regular expressions. They are called "the signature regular expressions" and are used as follows:
let max amount of persons = value integer 10;
type person_id = 1..<max amount of persons>;
type information = { person (X:person_id) likes person (Y:person_id) is (B:boolean)};
expand(2);
<create new signature regular expression "person (X:integer) likes person (Y:integer) is (B:boolean)">;
let my signature regular expression index = <the created signature regular expression index>;
let the match expression index = <my signature regular expression index>;
<match person2likesperson3isfalse>;
# for the signature 'person 2 likes person 3 is false', the result should be true
<print <the match result>>; # a predefined boolean variable
<print "match group integer" (X:1..2) <the match group "integer" (X:1..2)>>;
<print <the match group "boolean" 3>>;
The above snippet will print out:
true match group integer 1 2 match group integer 2 3 false