/////////////////////////////////////////////////////////////////////////////// // This file is generated automatically using Prop (version 2.3.0), // last updated on Feb 5, 1997. // The original source file is "inference.pC". /////////////////////////////////////////////////////////////////////////////// #define PROP_INFERENCE_USED #include ////////////////////////////////////////////////////////////////////////////// // This is a simple self-contained test to benchmark the speed of // naive inferencing in Prop. // // To compile on Unix: // // prop triangle.pcc // gcc -I triangle.cc -o triangle -L // -lad -liostream -lg++ ////////////////////////////////////////////////////////////////////////////// #include ////////////////////////////////////////////////////////////////////////////// // // Defines two relations to be used during inference // ////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Forward class definition for Number /////////////////////////////////////////////////////////////////////////////// #ifndef datatype_Number_defined #define datatype_Number_defined typedef class a_Number * Number; #endif /////////////////////////////////////////////////////////////////////////////// // Class hierarchy for datatype Number /////////////////////////////////////////////////////////////////////////////// class a_Number; // base class for datatype Number /////////////////////////////////////////////////////////////////////////////// // Base class for datatype 'Number' /////////////////////////////////////////////////////////////////////////////// class a_Number : public Fact { public: inline friend int boxed(const a_Number * x) { return 1; } inline friend int untag(const a_Number * x) { return 0; } int num; inline a_Number (int _xnum) : num(_xnum) {} inline friend a_Number * num (int _xnum) { return new a_Number (_xnum); } inline virtual ~a_Number() {} static RelTag relation_tag; virtual RelTag get_tag() const; }; /////////////////////////////////////////////////////////////////////////////// // Forward class definition for Limit /////////////////////////////////////////////////////////////////////////////// #ifndef datatype_Limit_defined #define datatype_Limit_defined typedef class a_Limit * Limit; #endif /////////////////////////////////////////////////////////////////////////////// // Class hierarchy for datatype Limit /////////////////////////////////////////////////////////////////////////////// class a_Limit; // base class for datatype Limit /////////////////////////////////////////////////////////////////////////////// // Base class for datatype 'Limit' /////////////////////////////////////////////////////////////////////////////// class a_Limit : public Fact { public: inline friend int boxed(const a_Limit * x) { return 1; } inline friend int untag(const a_Limit * x) { return 0; } int limit; inline a_Limit (int _xlimit) : limit(_xlimit) {} inline friend a_Limit * limit (int _xlimit) { return new a_Limit (_xlimit); } inline virtual ~a_Limit() {} static RelTag relation_tag; virtual RelTag get_tag() const; }; /////////////////////////////////////////////////////////////////////////////// // Relation class Number interface /////////////////////////////////////////////////////////////////////////////// Fact::RelTag a_Number::relation_tag = 0; static InitialiseFact Number_dummy__(a_Number::relation_tag); Fact::RelTag a_Number::get_tag() const { return a_Number::relation_tag; } /////////////////////////////////////////////////////////////////////////////// // Relation class Limit interface /////////////////////////////////////////////////////////////////////////////// Fact::RelTag a_Limit::relation_tag = 0; static InitialiseFact Limit_dummy__(a_Limit::relation_tag); Fact::RelTag a_Limit::get_tag() const { return a_Limit::relation_tag; } ////////////////////////////////////////////////////////////////////////////// // // The following inference construct defines an inference class // with two rules and one axiom. // ////////////////////////////////////////////////////////////////////////////// class Triangle : public Rete { Triangle(const Triangle&); void operator = (const Triangle&); public: static const Node network_table[]; static const RelationTable relation_table[]; public: Triangle(); virtual const char * name_of() const; void initialise_axioms(); protected: virtual void alpha_test (int, int, Fact *); virtual int beta_test (Join, Fact * []); virtual void action (RuleId, Fact * []); private: }; const char * Triangle::name_of() const { return "Triangle"; } /////////////////////////////////////////////////////////////////////////////// // Single object tests for inference class Triangle /////////////////////////////////////////////////////////////////////////////// void Triangle::alpha_test(int predicate__, int i__, Fact * fact__) { Fact * f__[3]; switch (predicate__) { case 1: { Number _0 = (Number)(f__[0] = fact__); { const unsigned char * m__; { static const unsigned char matched_set__[1] = { 15 }; m__ = matched_set__; } { if (i__) insert_alpha(4,fact__); else remove_alpha(4,fact__); } { if (i__) insert_alpha(3,fact__); else remove_alpha(3,fact__); } { if (i__) insert_beta(3,f__); else remove_beta(3,f__); } { if (i__) insert_beta(1,f__); else remove_beta(1,f__); } }} break; case 2: { Limit _0 = (Limit)(f__[0] = fact__); { const unsigned char * m__; { static const unsigned char matched_set__[1] = { 1 }; m__ = matched_set__; } { if (i__) insert_alpha(1,fact__); else remove_alpha(1,fact__); } }} break; } } /////////////////////////////////////////////////////////////////////////////// // Joins for inference class Triangle /////////////////////////////////////////////////////////////////////////////// int Triangle::beta_test(Join join__, Fact * f__[]) { switch (join__) { case 1: { Number _0 = (Number )f__[0]; Limit _1 = (Limit )f__[1]; return (_0->num < _1->limit); } case 3: { Number _0 = (Number )f__[0]; Number _1 = (Number )f__[1]; return (_0->num < _1->num); } case 4: { Number _0 = (Number )f__[0]; Number _1 = (Number )f__[1]; Number _2 = (Number )f__[2]; return ((_1->num < _2->num) && (((_0->num * _0->num) + (_1->num * _1->num)) == (_2->num * _2->num))); } default: return 0; } } /////////////////////////////////////////////////////////////////////////////// // Actions for inference class Triangle /////////////////////////////////////////////////////////////////////////////// void Triangle::action(Triangle::RuleId r__, Fact * f__[]) { switch (r__) { case 1: { Number _0 = (Number )f__[0]; Limit _1 = (Limit )f__[1]; assert_fact(num((_0->num + 1))); } break; case 2: { Number _0 = (Number )f__[0]; Number _1 = (Number )f__[1]; Number _2 = (Number )f__[2]; cout << _0->num << " * " << _0->num << " + " << _1->num << " * " << _1->num << " = " << _2->num << " * " << _2->num << '\n'; } break; } } /////////////////////////////////////////////////////////////////////////////// // Dispatch table for inference class Triangle /////////////////////////////////////////////////////////////////////////////// const Triangle::RelationTable Triangle::relation_table[] = { { &a_Number::relation_tag, 1, "Number" }, { &a_Limit::relation_tag, 2, "Limit" } }; /////////////////////////////////////////////////////////////////////////////// // Network table for inference class Triangle /////////////////////////////////////////////////////////////////////////////// const Triangle::Node Triangle::network_table[] = { { 0, 0, ReteNet::Node::Bot, 0, 0 } /* 0 */, { 1, 2, ReteNet::Node::And, 1, 2 } /* 1 */, { 0, 2, ReteNet::Node::Bot, 0, 1 } /* 2 */, { 1, 3, ReteNet::Node::And, 3, 4 } /* 3 */, { 2, 3, ReteNet::Node::And, 4, 5 } /* 4 */, { 0, 3, ReteNet::Node::Bot, 0, 2 } /* 5 */ }; /////////////////////////////////////////////////////////////////////////////// // Axioms for inference class Triangle /////////////////////////////////////////////////////////////////////////////// void Triangle::initialise_axioms() { assert_fact(num(1)); } /////////////////////////////////////////////////////////////////////////////// // Constructor for inference class Triangle /////////////////////////////////////////////////////////////////////////////// Triangle::Triangle() : Rete(6,Triangle::network_table,2,Triangle::relation_table) { initialise_axioms(); } int main() { Triangle triangle; // instantiate an inference module int top; /////////////////////////////////////////////////////////////////////////// // // Get the limit // /////////////////////////////////////////////////////////////////////////// cout << "Please input a limit (say, between 10 - 100): " << flush; cin >> top; cout << "Trying all numbers from 1 to " << top << '\n'; /////////////////////////////////////////////////////////////////////////// // // Insert the initial parameter into the database. // /////////////////////////////////////////////////////////////////////////// triangle << limit (top); /////////////////////////////////////////////////////////////////////////// // // Run the inference engine until it is stable. // The inference rules defined above will be fired and triangular // identities will be printed. // /////////////////////////////////////////////////////////////////////////// triangle.infer(); return 0; } /* ------------------------------- Statistics ------------------------------- Merge matching rules = yes Number of DFA nodes merged = 0 Number of ifs generated = 0 Number of switches generated = 0 Number of labels = 0 Number of gotos = 0 Adaptive matching = disabled Fast string matching = disabled Inline downcasts = disabled -------------------------------------------------------------------------- */