Task

Write a boolean function that tells whether a given integer is prime using Wilson's theorem.

By Wilson's theorem, a number p is prime if and only if p divides (p - 1)! + 1.

Remember that 1 and all non-positive integers are not prime.



See also

 Cut-the-knot: Wilson's theorem.
 Wikipedia: Wilson's theorem


/* PRIMALITY BY WILSON'S THEOREM */
wilson_100H: procedure options                                                  (main);
 
/* PL/I DEFINITIONS                                                             */
%include 'pg.inc';
/* PL/M DEFINITIONS: CP/M BDOS SYSTEM CALL AND CONSOLE I/O ROUTINES, ETC. */    /*
   DECLARE BINARY LITERALLY 'ADDRESS', CHARACTER LITERALLY 'BYTE';
   DECLARE SADDR  LITERALLY '.',       BIT       LITERALLY 'BYTE';
   BDOSF: PROCEDURE( FN, ARG )BYTE;
                               DECLARE FN BYTE, ARG ADDRESS; GOTO 5;   END; 
   BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5;   END;
   PRCHAR:   PROCEDURE( C );   DECLARE C CHARACTER; CALL BDOS( 2, C ); END;
   PRNL:     PROCEDURE;        CALL PRCHAR( 0DH ); CALL PRCHAR( 0AH ); END;
   PRNUMBER: PROCEDURE( N );
      DECLARE N ADDRESS;
      DECLARE V ADDRESS, N$STR( 6 ) BYTE, W BYTE;
      N$STR( W := LAST( N$STR ) ) = '$';
      N$STR( W := W - 1 ) = '0' + ( ( V := N ) MOD 10 );
      DO WHILE( ( V := V / 10 ) > 0 );
         N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
      END; 
      CALL BDOS( 9, .N$STR( W ) );
   END PRNUMBER;
   MODF: PROCEDURE( A, B )ADDRESS;
      DECLARE ( A, B )ADDRESS;
      RETURN( A MOD B );
   END MODF;
/* END LANGUAGE DEFINITIONS */
 
   /* TASK */
   DECLARE N BINARY;
 
   ISWILSONPRIME: PROCEDURE( N )returns                                         (
                                BIT                                             )
                                ;
      DECLARE N            BINARY;
      DECLARE ( FMODP, I ) BINARY;
      FMODP = 1;
      DO I = 2 TO N - 1;
         FMODP = MODF( FMODP * I, N );
      END;
      RETURN ( FMODP = N - 1 );
   END ISWILSONPRIME ;
 
   DO N = 1 TO 100;
      IF ISWILSONPRIME( N ) THEN DO;
         CALL PRCHAR( ' ' );
         CALL PRNUMBER( N );
      END;
   END;
 
EOF: end wilson_100H ;