@@ -398,5 +398,101 @@ churchSuite.add("boolean type conversion", assert => {
398398 assert . is ( toJsBool ( toChurchBoolean ( false ) ) , false ) ;
399399} ) ;
400400
401+ // result is the sc pair of sum and carry
402+ const halfAdder = a => b => sc => sc ( xor ( a ) ( b ) ) ( and ( a ) ( b ) ) ;
403+
404+ churchSuite . add ( "half adder from church booleans" , assert => {
405+ assert . is ( halfAdder ( F ) ( F ) ( fst ) , F ) ; // sum
406+ assert . is ( halfAdder ( F ) ( T ) ( fst ) , T ) ; // sum
407+ assert . is ( halfAdder ( T ) ( F ) ( fst ) , T ) ; // sum
408+ assert . is ( halfAdder ( T ) ( T ) ( fst ) , F ) ; // sum
409+
410+ assert . is ( halfAdder ( F ) ( F ) ( snd ) , F ) ; // carry
411+ assert . is ( halfAdder ( F ) ( T ) ( snd ) , F ) ; // carry
412+ assert . is ( halfAdder ( T ) ( F ) ( snd ) , F ) ; // carry
413+ assert . is ( halfAdder ( T ) ( T ) ( snd ) , T ) ; // carry !
414+ } ) ;
415+
416+ const fullAdder = a => b => c => // DIN 40900
417+ sc => {
418+ const hab = halfAdder ( a ) ( b ) ;
419+ const habSum = hab ( fst ) ;
420+ const habCar = hab ( snd ) ;
421+ const hcHabSum = halfAdder ( c ) ( habSum ) ;
422+ return sc
423+ ( hcHabSum ( fst ) )
424+ ( or ( habCar ) ( hcHabSum ( snd ) ) ) ;
425+ } ;
426+
427+ churchSuite . add ( "full adder from church booleans" , assert => {
428+ // full adder has three inputs (two boolean digits and a carry)
429+ // and has two outputs - a boolean digit and a new carry
430+
431+ // a full adder variant without half-adder compositions
432+ // const fullAdder = a => b => c =>
433+ // sc => sc
434+ // ( c (beq(a)(b)) (xor(a)(b)) )
435+ // ( c ( or(a)(b)) (and(a)(b)) );
436+
437+
438+ assert . is ( fullAdder ( F ) ( F ) ( F ) ( fst ) , F ) ; // sum
439+ assert . is ( fullAdder ( T ) ( F ) ( F ) ( fst ) , T ) ;
440+ assert . is ( fullAdder ( F ) ( T ) ( F ) ( fst ) , T ) ;
441+ assert . is ( fullAdder ( T ) ( T ) ( F ) ( fst ) , F ) ;
442+
443+ assert . is ( fullAdder ( F ) ( F ) ( T ) ( fst ) , T ) ; // sum with carry
444+ assert . is ( fullAdder ( T ) ( F ) ( T ) ( fst ) , F ) ;
445+ assert . is ( fullAdder ( F ) ( T ) ( T ) ( fst ) , F ) ;
446+ assert . is ( fullAdder ( T ) ( T ) ( T ) ( fst ) , T ) ;
447+
448+ assert . is ( fullAdder ( F ) ( F ) ( F ) ( snd ) , F ) ; // new carry when old carry is false
449+ assert . is ( fullAdder ( T ) ( F ) ( F ) ( snd ) , F ) ;
450+ assert . is ( fullAdder ( F ) ( T ) ( F ) ( snd ) , F ) ;
451+ assert . is ( fullAdder ( T ) ( T ) ( F ) ( snd ) , T ) ;
452+
453+ assert . is ( fullAdder ( F ) ( F ) ( T ) ( snd ) , F ) ; // new carry when carry is true
454+ assert . is ( fullAdder ( T ) ( F ) ( T ) ( snd ) , T ) ;
455+ assert . is ( fullAdder ( F ) ( T ) ( T ) ( snd ) , T ) ;
456+ assert . is ( fullAdder ( T ) ( T ) ( T ) ( snd ) , T ) ;
457+
458+ } ) ;
459+
460+ churchSuite . add ( "3 bit adder for church booleans" , assert => {
461+ const [ ThreeBit , b2 , b1 , b0 ] = Tuple ( 3 ) ;
462+ const threeBitAdder = a => b => {
463+ const sc0 = fullAdder ( a ( b0 ) ) ( b ( b0 ) ) ( F ) ; // rightmost carry is false
464+ const sc1 = fullAdder ( a ( b1 ) ) ( b ( b1 ) ) ( sc0 ( snd ) ) ; // pass on the carry
465+ const sc2 = fullAdder ( a ( b2 ) ) ( b ( b2 ) ) ( sc1 ( snd ) ) ; // and so on...
466+ return ThreeBit
467+ ( sc2 ( fst ) )
468+ ( sc1 ( fst ) )
469+ ( sc0 ( fst ) ) ;
470+ }
471+ ;
472+
473+ let result ;
474+
475+ result = threeBitAdder ( ThreeBit ( F ) ( F ) ( F ) ) ( ThreeBit ( F ) ( F ) ( F ) ) ; // 0 + 0 = 0
476+ assert . is ( result ( b0 ) , F ) ;
477+ assert . is ( result ( b1 ) , F ) ;
478+ assert . is ( result ( b2 ) , F ) ;
479+
480+ result = threeBitAdder ( ThreeBit ( F ) ( F ) ( T ) ) ( ThreeBit ( F ) ( F ) ( T ) ) ; // 1 + 1 = 2
481+ assert . is ( result ( b0 ) , F ) ;
482+ assert . is ( result ( b1 ) , T ) ;
483+ assert . is ( result ( b2 ) , F ) ;
484+
485+ result = threeBitAdder ( ThreeBit ( T ) ( T ) ( T ) ) ( ThreeBit ( F ) ( F ) ( F ) ) ; // 7 + 0 = 7
486+ assert . is ( result ( b0 ) , T ) ;
487+ assert . is ( result ( b1 ) , T ) ;
488+ assert . is ( result ( b2 ) , T ) ;
489+
490+ result = threeBitAdder ( ThreeBit ( T ) ( T ) ( T ) ) ( ThreeBit ( F ) ( F ) ( T ) ) ; // 7 + 1 = 0
491+ assert . is ( result ( b0 ) , F ) ;
492+ assert . is ( result ( b1 ) , F ) ;
493+ assert . is ( result ( b2 ) , F ) ;
494+
495+ } ) ;
496+
401497
402498churchSuite . run ( ) ;
0 commit comments