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