// // A C++ program to test for the primality of the number 13 // // It has the curious property that it does no arithmetic // but uses only the template mechanism and class derivation // to achieve its result. It starts at the most basic axioms // of arithmetic starting with the definition of zero and // its successors... // // You'll need a good C++ compiler. // // (c) D Piponi (But copy it as much as you like if you credit me) // // // First a little trick to find the base class of our // classes because the template mechanism requires // exact matches. // // Two values are considered equivalent if they have // the same baseclass. For example 1+1 isn't // identical to 2 but 1+1 *is* derived from 2. // template struct Value { typedef V value; }; // // Define zero // struct zero : public Value { }; // // Define the successor of an integer // template struct S : public Value > { typedef C predecessor; }; // // Now we have the integers. So introduce some convenience // types. // typedef S one; typedef S two; typedef S three; typedef S four; typedef S five; typedef S six; typedef S seven; typedef S eight; typedef S nine; typedef S ten; // // Define plus,... // template struct plus : public S > { }; template struct plus : public C { }; // // ...minus... // template struct minus : public minus::predecessor { }; template struct minus : public C { }; // // ...and times. // template struct times : public plus::value> { }; template struct times : public zero { }; // // Define the usual ordering on the integers. // template struct ge : public ge { }; template struct ge : public one { }; template struct ge : public zero { }; template<> struct ge : public one { }; // // Divisibility testing // template > > struct Divisible { }; template struct Divisible > > : public Divisible::value> { }; // // The case C struct Divisible : public zero { }; template struct Divisible : public one { }; // // The case C>=D: // D divides C iff D divides C-D. // template struct Divisible > : public Divisible::value,D> { }; // // Primality testing // template struct Prime { }; // // We use recursion to set up a loop from 2 to one less // than the integer we are testing. Essentially this is a state machine // using template parameters to record the current state. // // Are we at the end of the recursion? // template struct Prime : public Prime::value> { }; // // Test potential factor D, trying successor on failure. // template struct Prime : public Prime,zero,typename Divisible::value,zero> { }; // // Found a factor. // template struct Prime : public zero { }; // // Reached the end of the loop without finding divisor. // template struct Prime : public one { }; // // Convenience method for humans allowing input of // numbers in decimal format. // template struct Decimal : public plus::value,D> { }; // // Unfortunately the I/O interface spoils the purity of it all. // #include template char *output(C); template<> char *output(zero) { return "No"; } template<> char *output(one) { return "Yes"; } main() { // // Is 13 prime? // puts(output(Prime::value>::value())); }