;; hume y berk[eley]

;; aritmetica con naturales

;; suma
(0 + X)			X
((s X) + Y)		(X + (s Y))

;; resta
(X - 0)			X
((s X) - (s Y))		(X - Y)
(0 - (s Y))		error

;; multiplicacion
(0 * X)			0
((s X) * Y)		(Y + (X * Y))

;; division entera
(X div 0)		error
(0 div X)		0
((s X) div (s Y))	(if (X < Y)
			 0
			 (s (((s X) - (s Y)) div (s Y))))

;; resto
(X mod 0)		error
(0 mod X)		0
((s X) mod (s Y))	(if (X < Y)
			 (s X)
			 (((s X) - (s Y)) mod (s Y)))

(par X)			((X mod 2) = 0)
impar			(composicion not par)

;; potencia
(X ^ 0)			1
(X ^ (s Y))		(X * (X ^ Y))

;; mcd
(mcd 0 0)		error
(mcd 0 X)		X
(mcd X 0)		X
(mcd (s X) (s Y))	(if (((s X) mod (s Y)) = 0)
			 (s Y)
			 (mcd (s Y) ((s X) mod (s Y))))

;; mcm
(mcm X Y)		((X * Y) div (mcd X Y))

;; operadores relacionales

(0 = 0)			v
(0 = (s X))		f
((s X) = 0)		f
((s X) = (s Y))		(X = Y)

(0 <= X)		v
((s X) <= 0)		f
((s X) <= (s Y))	(X <= Y)

(0 >= 0)		v
(0 >= (s X))		f
((s X) >= 0)		v
((s X) >= (s Y))	(X >= Y)

(X < Y)			(not (X >= Y))
(X > Y)			(not (X <= Y))
(X != Y)		(not (X = Y))

;; puaj...

1			(s 0)
2			(s 1)
3			(s 2)
4			(s 3)
5			(s 4)
6			(s 5)
7			(s 6)
8			(s 7)
9			(s 8)

;; booleanos

(v && X)		X
(f && X)		f

(v || X)		v
(f || X)		X

(not v)			f
(not f)			v

(if v A B)		A
(if f A B)		B

;; unlambdaizacion a.k.a cuchificacion

(lambda ARG ARG)	_i
(lambda ARG (A B))	((_s1 (lambda ARG A)) (lambda ARG B))
(lambda ARG (A B C))	(((_s2 (lambda ARG A)) (lambda ARG B)) (lambda ARG C))
(lambda ARG (A B C D))	((((_s3 (lambda ARG A)) (lambda ARG B)) (lambda ARG C))
			 (lambda ARG D))
(lambda ARG CONST)	(_k CONST)

;; pa escribir menos
\			lambda	

;; combinadores

(_i X)			X
((_k X)	Y)		X
(((_s1 A) B) Z)		((A Z) (B Z))
((((_s2 A) B) C) Z)	((A Z) (B Z) (C Z))
(((((_s3 A) B) C) D) Z)	((A Z) (B Z) (C Z) (D Z))

;; por ejemplo

doble			(\ x (x * 2))
incrementador		(\ x (\ y (x + y)))
inc5			(incrementador 5)

;; (puaj de nuevo pero me reconforto con la idea de
;; que Haskell tiene puajs parecidos con zip, zip3
;; y los cerdos constructores (,,,))

;; listas

(car (cons X Y))	X
(cdr (cons X Y))	Y

(nth 0 (cons X Y))	X
(nth (s N) (cons X Y))	(nth N Y)
(nth X nil)		error

;; repuaj

(list A)		(cons A nil)
(list A B)		(cons A (list B))
(list A B C)		(cons A (list B C))
(list A B C D)		(cons A (list B C D))
(list A B C D E)	(cons A (list B C D E))
(list A B C D E F)	(cons A (list B C D E F))

;; primeros n elementos de una lista
(head 0 X)		nil
(head (s N) (cons X Y))	(cons X (head N Y))	
(head X nil)		error

;; alto orden -- ojo no currificados pero bien podrian con
;; algunos parentesis mas

(map F nil)		nil 
(map F (cons X XS))	(cons (F X) (map F XS))

(foldl F V nil)		V
(foldl F V (cons X XS))	(F X (foldl F V XS))

(filter P nil)		nil
(filter P (cons X XS))	(if (P X)
			 (cons X (filter P XS))
			 (filter P XS))

;; listas infinitas
;;   hago como que funcionan, pero en realidad
;;   hay infinitos :-P problemas. (el problema
;;   aparece cuando para matchear hay que reducir
;;   una lista infinita antes que otro argumento...
;;   nunca empieza a reducir el otro!)

tristeza		(cons nao-tem-fim tristeza)
enteros			(cons 0 (map s enteros))

;; esto es un raro invento infinito
;; como el arbol binario eterno que nunca
;; pude dibujar :(
puaj			(puaj puaj)

;; lo ``bueno'' es que los puajes tienen todos
;; una razon parecida. la razon es...
;; este lenguaje es una mierda.

;; ahhhhh dulce venganza

((composicion F G) X)	(F (G X))
((op->fun OP) A B)	(A OP B)
(A (fun->op F) B)	(F A B)

;; que lindooo
;; (tarda un rato)

pares			(filter par enteros)
doce			(foldl (op->fun +) 0 (head 4 pares))
