; Reminder and Division in Church Numerals
; ----------------------------------------

; I promised that I will show how they were done so here goes:

(define greater-or-equal
(lambda (x)
	(lambda (y)
		((less-or-equal y) x)
	)
))

(define reminder_helper
(Y (lambda (f)
	(lambda (x)
		(((lambda (div)
			(lambda (div_by)
				(((((greater-or-equal div) div_by)
					(lambda (no_use)
						(f ((lc_cons
							((subtract div) div_by))
							div_by))
					))
					(lambda (no_use)
						div
					))
					zero
				)
			)
		) (lc_car x)) (lc_cdr x))
	)
)))

(define reminder
(lambda (div)
	(lambda (div_by)
		(reminder_helper ((lc_cons div) div_by))
	)
))

(display (church->int ((reminder (int->church 100)) (int->church 9))))
(newline)

(define divide_helper
(Y (lambda (f)
	(lambda (x)
		(((lambda (div)
			(lambda (div_by)
				(((((greater-or-equal div) div_by)
					(lambda (no_use)
						(succ (f ((lc_cons
							((subtract div) div_by))
							div_by)))
					))
					(lambda (no_use)
						zero
					))
					zero
				)
			)
		) (lc_car x)) (lc_cdr x))
	)
)))

(define divide
(lambda (div)
	(lambda (div_by)
		(divide_helper ((lc_cons div) div_by))
	)
))

(display "50/8=")
(display (church->int ((divide (int->church 50)) (int->church 8))))
(newline)

; Note that the version of divide does not use tail-recursion.
; Thus, it will consume a memory of O(div/div_by). Still, a tail
; recursion version can be written using a three-elements
;( div, div_by, accumulator) list.