.gitignore
[prop.git] / tools / demos / dates.pcc
blob89d19d6a411d055cceae8589737cf2fd159e3e18
1 //
2 //  This is a simple self-contained test of Prop's inference formalism.
3 //
4 //  To compile on Unix: 
5 //
6 //     prop dates.pcc
7 //     gcc -I<prop-include-dir> dates.cc -o dates -L<ADLib-library-dir>
8 //         -lad -liostream -lg++
9 //
11 #include <string.h>
12 #include <iostream.h>
15 // Defines a simple relation(this should be placed in an include file).
16 // Notice that this relation is actually a variant.
17 // In general, we allow variant relations and relations
18 // with arbitrarily complex arguments, just like any ``datatypes.''
19 // In fact, an ``relation'' can be used as a datatype in Prop's
20 // other pattern matching constructs.
22 relation Person = male   (char *)
23                 | female (char *) 
24                 ;
26 relation Animal = animal (char *);
29 // Instantiate the relation: Prop will generate additional methods to
30 // implement the relation type.
31 // (This should be placed in an implementation file.)
33 instantiate relation Person, Animal;
36 // The inference construct defines a new inference class with
37 // a set of inference rules.  Each instance of Dates should be
38 // considered an independent (deductive) database.
40 inference class Dates {};
41 inference Dates {
43      //
44      // First, say hello to myself, the author.
45      //
46      male ("allen")
47  ->  { cout << "Hi Al\n"; };
49      //
50      // print all names
51      //
52      male (p) 
53  ->  { cout << p << " is here\n"; };
54      female (p) 
55  ->  { cout << p << " is here\n"; };
57      //
58      // Print all pairs of potential couples.
59      // This is basically a simple cartesian product.
60      //
61      male (m) and female (f)
62  ->  { cout << "Heterosexual couple " << m << " and " << f << '\n'; };
64      //
65      // This is the 90's, so try gays and lesbians too.
66      // But make sure we don't print duplicates.
67      //
68      male (m1) and male (m2) where (strcmp(m1,m2) < 0)
69  ->  { cout << "Gay couple " << m1 << " and " << m2 << '\n'; };
71      female (f1) and female (f2) where (strcmp(f1,f2) < 0)
72  ->  { cout << "Lesbian couple " << f1 << " and " << f2 << '\n'; };
76 int main()
77 {  // Instantiate an inference object
78    Dates dates;  
80    //
81    // Insert some facts
82    //
83    dates << male("mike") 
84          << male("vijay")
85          << male("allen")
86          << male("neal")
87          << female("holly")
88          << female("rachel")
89          << female("beth")
90          << female("jessica")
91          << female("michele")
92          ;
94    //
95    // These facts will not fire any rules, of course.
96    //
97    dates << animal ("monkey")
98          << animal ("weasel")
99          ;
101    //
102    // Run the inference engine until it is stable.
103    // The inference rules defined above will be fired and dating
104    // candidates will be printed.  Notice that the order in which
105    // this occurs is non-deterministic.
106    //
107    dates.infer();
109    //
110    // The above is actually an abbreviation for the following loop.
111    //
112    // while (! dates.is_stable())   // while not stable
113    //    dates.fire();              // execute one rule
114    //
116    //
117    // Clears the database.  
118    // It doesn't have any observable effect in our example, however.
119    //
120    dates.clear();
122    return 0;