1 /**
2 * This module defines the notion of a $(RULE). A $(RULE) is the part of
3 * a $(I cellular automaton) responsible for changing the $(I ca)'s $(I cells) state.
4 * Each generation the $(RULE) is applied to the $(I cellular automaton) in order to
5 * get it's $(I cells) new state.
6 *
7 * It provides templates for testing whether a given object is a $(RULE), and
8 * what kind of $(RULE) it is.
9 *
10 * $(CALIB_ABSTRACT_DESC)
11 */
12 
13 module caLib_abstract.rule;
14 
15 /**
16 * Tests if something is a $(B Rule), defined as having a primitive `applyRule`
17 *
18 * returns `true` if `T` is a $(B Rule). A $(B Rule) is the most
19 * basic form of a $(CU rule). It must define the primitive
20 * `void applyRule()`.
21 *
22 * params: T = the type to be tested
23 *
24 * returns: true if T is a $(B Rule), false if not
25 */
26 enum isRule(T) =
27     is(typeof(T.init.applyRule()) : void);
28 
29 ///
30 unittest
31 {
32     struct A { void applyRule() {} }
33     struct B { int applyRule(int b) { return int.init; } }
34     
35     static assert( isRule!A );
36     static assert(!isRule!B );
37     static assert(!isRule!string );
38 }
39 
40 
41 
42 /// Example of a $(B Rule)
43 struct Rule
44 {
45     void applyRule() {}
46 }
47 
48 ///
49 unittest
50 {
51     assert(isRule!Rule);
52 }
53 
54 
55 
56 /**
57 * Tests if something is a $(B ReversibleRule), defined as being a $(B Rule) with
58 * the additional primitive `applyRuleReverse` 
59 *
60 * returns `true` if `T` is a $(B ReversibleRule). A $(B ReversibleRule) can "reverse"
61 * the state of a $(I ca) to its previours state. It must define the primitive
62 * `void applyRuleReverse()`, in addition to the primitives defined in $(B Rule)
63 *
64 * params: T = the type to be tested
65 *
66 * returns: true if T is a $(B ReversibleRule), false if not
67 */
68 enum isReversibleRule(T) =
69     isRule!T &&
70     is(typeof(T.init.applyRuleReverse()) : void);
71 
72 ///
73 unittest
74 {
75     struct A
76     {
77         void applyRule() {}
78         void applyRuleReverse() {}
79     }
80     
81     static assert( isRule!A );
82     static assert(!isRule!string );
83 }
84 
85 
86 
87 /// Example of a $(B ReversibleRule)
88 struct ReversibleRule
89 {
90     void applyRule() {}
91     void applyRuleReverse() {}
92 }
93 
94 ///
95 unittest
96 {
97     assert( isRule!ReversibleRule);
98     assert( isReversibleRule!ReversibleRule);
99     assert(!isReversibleRule!Rule);
100 }