usar simbolos opciones librerias instalar importar hacer ejemplos compilador como haskell functional-programming proof

simbolos - Pruebas funcionales(Haskell)



instalar haskell en ubuntu (4)

Fallé en la lectura de RWH; y no renuncié, ordené a Haskell: el oficio de la programación funcional . Ahora tengo curiosidad acerca de estas pruebas funcionales en la página 146. Específicamente estoy tratando de probar la sum (reverse xs) = sum xs 8.5.1 sum (reverse xs) = sum xs . Puedo hacer algunas de las pruebas de inducción pero luego me quedo atascado ..

HYP:

sum ( reverse xs ) = sum xs

BASE:

sum ( reverse [] ) = sum [] Left = sum ( [] ) (reverse.1) = 0 (sum.1) Right = 0 (sum.1)

INDUCCIÓN:

sum ( reverse (x:xs) ) = sum (x:xs) Left = sum ( reverse xs ++ [x] ) (reverse.2) Right = sum (x:xs) = x + sum xs (sum.2)

Así que ahora solo estoy tratando de probar que la sum ( reverse xs ++ [x] ) Left sum ( reverse xs ++ [x] ) es igual a la x + sum xs Right , pero eso no está muy lejos de donde empecé la sum ( reverse (x:xs) ) = sum (x:xs) .

No estoy muy seguro de por qué esto debe probarse, parece totalmente razonable usar la prueba simbólica de reverse x:y:z = z:y:x (por definición), y porque + es conmutativo (arth) y luego reverse 1+2+3 = 3+2+1 ,


Aquí es donde creo que estás atrapado. Necesitas probar un lema que diga

sum (xs ++ ys) == sum xs + sum ys

Para probar esta ley, tendrá que asumir que la suma es asociativa, lo cual es cierto solo para enteros y racionales.

Luego, también deberá asumir que la suma es conmutativa, lo que es cierto para enteros y racionales, pero también para flotadores.

Digresión: El estilo de tus pruebas me parece muy extraño. Creo que le será más fácil escribir este tipo de pruebas si usa el estilo en el libro de Graham Hutton .


Básicamente necesitas demostrar que

sum (reverse xs ++ [x]) = sum (reverse xs) + sum [x]

que luego conduce fácilmente a

= x + sum (reverse xs) = x + sum xs -- by inductive hyp.

El problema es mostrar que la sum distribuye sobre la concatenación de listas.


Usa la definición de una suma para dividir (suma inversa xs ++ [x]) en x + suma (inversa (xs)), y usando tu hipótesis inductiva, sabes suma (inversa (xs)) = suma (xs). Pero estoy de acuerdo, la inducción es una exageración para un problema como este.


sum (reverse []) = sum [] -- def reverse sum (reverse (x:xs)) = sum (reverse xs ++ [x]) -- def reverse = sum (reverse xs) + sum [x] -- sum lemma below = sum (reverse xs) + x -- def sum = x + sum (reverse xs) -- commutativity assumption! = x + sum xs -- inductive hypothesis = sum (x:xs) -- definition of sum

Sin embargo, hay suposiciones subyacentes de asociatividad y conmutatividad que no están estrictamente garantizadas y esto no funcionará correctamente para una serie de tipos numéricos como Float y Double donde se violan esas suposiciones.

Lema: sum (xs ++ ys) == sum xs + sum ys dada la asociatividad de (+)

Prueba:

sum ([] ++ ys) = sum ys -- def (++) = 0 + sum ys -- identity of addition = sum [] ++ sum ys -- def sum sum ((x:xs) ++ ys) = sum (x : (xs ++ ys)) -- def (++) = x + sum (xs ++ ys) -- def sum = x + (sum xs + sum ys) -- inductive hypothesis = (x + sum xs) + sum ys -- associativity assumption! = sum (x:xs) + sum ys -- def sum