1+ import { readFileSync } from "fs" ;
2+ import { assert } from "chai" ;
3+
4+ import * as LC from "../../src/lambda-calculus.js" ;
5+
6+ const Zero = end => even => odd => end ;
7+ const Bit0 = n => end => even => odd => even ( n ) ;
8+ const Bit1 = n => end => even => odd => odd ( n ) ;
9+ const fromInt = n => n ? n & 1 ? Bit1 ( fromInt ( - ( n >> 1 ) ) ) : Bit0 ( fromInt ( - ( n >> 1 ) ) ) : Zero ;
10+ const padded = m => m ( false ) ( n => n ( true ) ( ( ) => padded ( n ) ) ( padded ) ) ( padded ) ;
11+ const unsafeToInt = m => m ( 0 ) ( n => - 2 * unsafeToInt ( n ) ) ( n => 1 - 2 * unsafeToInt ( n ) ) ;
12+ const toInt = n => {
13+ if ( padded ( n ) )
14+ throw new TypeError ( `toInt: padded number ${ unsafeToInt ( n ) } ` ) ;
15+ else
16+ return unsafeToInt ( n ) ;
17+ } ;
18+ LC . configure ( { purity : "LetRec" , numEncoding : { fromInt, toInt } , verbosity : "Concise" } ) ;
19+
20+ const solutionText = readFileSync ( new URL ( "./solution.lc" , import . meta. url ) , { encoding : "utf8" } ) ;
21+ const solution = LC . compile ( solutionText ) ;
22+ const { succ, pred, add, negate, sub, zero, lt0, le0, ge0, gt0, compare } = solution ;
23+ const { True, False, LT , EQ , GT } = solution ;
24+
25+ const toBoolean = p => p ( true ) ( false ) ;
26+ const toOrdering = cmp => cmp ( "LT" ) ( "EQ" ) ( "GT" ) ;
27+
28+ describe ( "NegaBinaryScott" , ( ) => {
29+ it ( "numbers" , ( ) => {
30+ for ( let n = - 10 ; n <= 10 ; n ++ )
31+ assert . strictEqual ( toInt ( fromInt ( n ) ) , n , `toInt (fromInt ${ n } )` ) ;
32+ } ) ;
33+ it ( "succ" , ( ) => {
34+ for ( let n = - 10 ; n <= 10 ; n ++ )
35+ assert . strictEqual ( toInt ( succ ( fromInt ( n ) ) ) , n + 1 , `succ ${ n } ` ) ;
36+ // assert.strictEqual( toInt(pred(fromInt(n))), n-1, `pred ${ n }` );
37+ } ) ;
38+ it ( "pred" , ( ) => {
39+ for ( let n = - 10 ; n <= 10 ; n ++ )
40+ // assert.strictEqual( toInt(succ(fromInt(n))), n+1, `succ ${ n }` ),
41+ assert . strictEqual ( toInt ( pred ( fromInt ( n ) ) ) , n - 1 , `pred ${ n } ` ) ;
42+ } ) ;
43+ it ( "add" , ( ) => {
44+ for ( let m = - 10 ; m <= 10 ; m ++ )
45+ for ( let n = - 10 ; n <= 10 ; n ++ ) {
46+ const actual = toInt ( add ( fromInt ( m ) ) ( fromInt ( n ) ) ) ;
47+ assert . strictEqual ( actual , m + n , `add ${ m } ${ n } ` ) ;
48+ }
49+ } ) ;
50+ it ( "negate" , ( ) => {
51+ for ( let n = - 10 ; n <= 10 ; n ++ )
52+ assert . strictEqual ( toInt ( negate ( fromInt ( n ) ) ) , - n , `negate ${ n } ` ) ;
53+ } ) ;
54+ it ( "sub" , ( ) => {
55+ for ( let m = - 10 ; m <= 10 ; m ++ )
56+ for ( let n = - 10 ; n <= 10 ; n ++ ) {
57+ const actual = toInt ( sub ( fromInt ( m ) ) ( fromInt ( n ) ) ) ;
58+ assert . strictEqual ( actual , m - n , `sub ${ m } ${ n } ` ) ;
59+ }
60+ } ) ;
61+ it ( "eq, uneq" , ( ) => {
62+ for ( let n = - 10 ; n <= 10 ; n ++ )
63+ assert . equal ( toBoolean ( zero ( fromInt ( n ) ) ) , n === 0 , `zero ${ n } ` ) ,
64+ assert . equal ( toBoolean ( lt0 ( fromInt ( n ) ) ) , n < 0 , `lt0 ${ n } ` ) ,
65+ assert . equal ( toBoolean ( le0 ( fromInt ( n ) ) ) , n <= 0 , `le0 ${ n } ` ) ,
66+ assert . equal ( toBoolean ( ge0 ( fromInt ( n ) ) ) , n >= 0 , `ge0 ${ n } ` ) ,
67+ assert . equal ( toBoolean ( gt0 ( fromInt ( n ) ) ) , n > 0 , `gt0 ${ n } ` ) ;
68+ } ) ;
69+ it ( "compare" , ( ) => {
70+ for ( let m = - 10 ; m <= 10 ; m ++ )
71+ for ( let n = - 10 ; n <= 10 ; n ++ ) {
72+ const actual = toOrdering ( compare ( fromInt ( m ) ) ( fromInt ( n ) ) ) ;
73+ const expected = m > n ? "GT" : m < n ? "LT" : "EQ" ;
74+ assert . equal ( actual , expected , `compare ${ m } ${ n } ` ) ;
75+ }
76+ } ) ;
77+ } ) ;
0 commit comments