Skip to content

Commit b49771b

Browse files
committed
Archivo Clase2
1 parent 028a719 commit b49771b

File tree

1 file changed

+228
-0
lines changed

1 file changed

+228
-0
lines changed

Clase2.fst

+228
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
module Clase2
2+
3+
(* Polimorfismo paramétrico y lógica constructiva. *)
4+
5+
(* La identidad polimórfica *)
6+
val id0_exp : (a:Type) -> a -> a
7+
let id0_exp = fun (a:Type) -> fun (x:a) -> x
8+
9+
// let id0_exp = fun (a:Type) -> fun (x:a) -> x
10+
let id_int : int -> int = id0_exp _
11+
let id_bool : bool -> bool = id0_exp _
12+
13+
let _ = assert (id_int 1 == 1)
14+
let _ = assert (id_bool true == true)
15+
16+
(* El símbolo # marca un argumento * implícito. Estos argumentos
17+
se insertan automáticamente por el typechecker cuando son requeridos.
18+
Si hay una única forma de resolverlos, dada otras restricciones en el contexto,
19+
F* usará esa solución. Si por alguna razón no puede resolverse automáticamente,
20+
siempre pueden darse de forma explícita usando un # en la aplicación. *)
21+
22+
let id (#a:Type) (x:a) : a = x
23+
// let id = fun (#a:Type) -> fun (x:a) -> x
24+
let id_int' : int -> int = id
25+
let id_bool' : bool -> bool = id
26+
27+
let _ = assert (id 1 == 1)
28+
let _ = assert (id true == true)
29+
30+
(* Un tipo verdaderemente dependiente *)
31+
val raro : bool -> Type0
32+
let raro (b:bool) : Type =
33+
if b
34+
then int
35+
else string
36+
37+
(* Una función con el tipo `raro`: devuelve un entero o una
38+
cadena según su argumento. *)
39+
let f_raro (x:bool) : raro x =
40+
if x then 123 else "hola"
41+
42+
let _ = assert (f_raro true == 123)
43+
let _ = assert (f_raro false == "hola")
44+
45+
(* (listas)^n de a *)
46+
let rec nlist (a:Type) (n:nat) : Type =
47+
match n with
48+
| 0 -> a
49+
| n -> list (nlist a (n-1))
50+
51+
let rec n_singleton (#a:_) (x:a) (n:nat) : nlist a n =
52+
match n with
53+
| 0 -> x
54+
| n -> [n_singleton x (n-1)]
55+
56+
let _ = assert (n_singleton 1 0 == 1)
57+
let _ = assert (n_singleton 1 1 == [1])
58+
let _ = assert (n_singleton 1 2 == [[1]])
59+
60+
(* Lógica constructiva *)
61+
62+
(*
63+
De la librería estándar de F*:
64+
65+
type tuple2 'a 'b = | Mktuple2 : _1: 'a -> _2: 'b -> tuple2 'a 'b
66+
let fst (x: tuple2 'a 'b) : 'a = Mktuple2?._1 x
67+
let snd (x: tuple2 'a 'b) : 'b = Mktuple2?._2 x
68+
69+
type either a b =
70+
| Inl : v: a -> either a b
71+
| Inr : v: b -> either a b
72+
73+
`a & b` es azúcar para `tuple2 a b`
74+
`(x,y)` es azúcar para `Mktuple2 x y`
75+
*)
76+
type yy (a b : Type) = a & b
77+
type oo (a b : Type) = either a b
78+
type falso =
79+
type verd = falso -> falso
80+
type no (a : Type) = a -> falso
81+
82+
let vv : verd = id
83+
84+
(* La conjunción conmuta *)
85+
let comm_yy (#a #b : Type) : yy a b -> yy b a =
86+
fun p -> (snd p, fst p)
87+
// fun (x, y) -> (y, x)
88+
89+
(* verd es neutro para la conjunción *)
90+
let neutro_yy (#a:Type) : yy a verd -> a =
91+
fun (x, _) -> x
92+
93+
let neutro_yy' (#a:Type) : a -> yy a verd =
94+
fun (x:a) -> (x, vv)
95+
96+
(* La disjunción conmuta *)
97+
(* `function` es azúcar para `fun` con un pattern matching inmediato al argumento. *)
98+
let comm_oo (#a #b : Type) : oo a b -> oo b a =
99+
function
100+
| Inl x -> Inr x
101+
| Inr y -> Inl y
102+
103+
(* Principio de explosión: falso no tiene constructores,
104+
así que con un match vacío podemos demostrar cualquier cosa *)
105+
let ex_falso (#a:Type) (f : falso) : a =
106+
match f with
107+
108+
(* Demostrar *)
109+
let neu1 (#a:Type) : oo a falso -> a =
110+
admit()
111+
112+
(* Demostrar *)
113+
let neu2 (#a:Type) : a -> oo a falso =
114+
admit()
115+
116+
(* Distribución de `yy` sobre `oo`, en ambas direcciones *)
117+
let distr_yyoo_1 (#a #b #c : Type)
118+
: yy a (oo b c) -> oo (yy a b) (yy a c)
119+
// a /\ (b \/ c) ==> (a /\ b) \/ (a /\ c)
120+
// a * (b + c) ==> (a * b) + (a * c)
121+
=
122+
fun (x, yz) ->
123+
match yz with
124+
| Inl y -> Inl (x, y)
125+
| Inr z -> Inr (x, z)
126+
127+
let distr_yyoo_2 (#a #b #c : Type)
128+
: oo (yy a b) (yy a c) -> yy a (oo b c)
129+
=
130+
admit()
131+
132+
let distr_ooyy_1 (#a #b #c : Type)
133+
: oo a (yy b c) -> yy (oo a b) (oo a c)
134+
=
135+
admit()
136+
137+
let distr_ooyy_2 (#a #b #c : Type)
138+
: yy (oo a b) (oo a c) -> oo a (yy b c)
139+
=
140+
admit()
141+
142+
let modus_tollens (#a #b : Type)
143+
: (a -> b) -> (no b -> no a)
144+
=
145+
admit()
146+
(* Vale la recíproca? *)
147+
148+
let modus_tollendo_ponens (#a #b : Type)
149+
: (oo a b) -> (no a -> b)
150+
=
151+
admit()
152+
(* Vale la recíproca? *)
153+
154+
let modus_ponendo_tollens (#a #b : Type)
155+
: no (yy a b) -> (a -> no b)
156+
=
157+
admit()
158+
(* Vale la recíproca? *)
159+
160+
(* Declare y pruebe, si es posible, las leyes de De Morgan
161+
para `yy` y `oo`. ¿Son todas intuicionistas? *)
162+
163+
let demorgan1_ida (#a #b : Type) : oo (no a) (no b) -> no (yy a b) =
164+
admit()
165+
166+
let demorgan1_vuelta (#a #b : Type) : no (yy a b) -> oo (no a) (no b) =
167+
admit()
168+
169+
let demorgan2_ida (#a #b : Type) : yy (no a) (no b) -> no (oo a b) =
170+
admit()
171+
172+
let demorgan2_vuelta (#a #b : Type) : no (oo a b) -> yy (no a) (no b) =
173+
admit()
174+
175+
176+
(* P y no P no pueden valer a la vez. *)
177+
let no_contradiccion (#a:Type) : no (yy a (no a)) =
178+
fun (x, f) -> f x
179+
180+
(* Mientras "quede" una negación, sí podemos eliminar doble
181+
negaciones. Pero no podemos llegar a una prueba de a.
182+
183+
Ver también el embebimiento de lógica clásica en lógica intuicionista
184+
via doble negación (spoiler: p se embebe como no (no p), y resulta equivalente
185+
a la lógica clásica. *)
186+
let elim_triple_neg (#a:Type) : no (no (no a)) -> no a =
187+
fun f a -> f (fun g -> g a)
188+
189+
(* Ejercicio. ¿Se puede en lógica intuicionista? *)
190+
let ley_impl1 (p q : Type) : (p -> q) -> oo (no p) q =
191+
admit()
192+
193+
(* Ejercicio. ¿Se puede en lógica intuicionista? *)
194+
let ley_impl2 (p q : Type) : oo (no p) q -> (p -> q) =
195+
admit()
196+
197+
(* Ejercicio. ¿Se puede en lógica intuicionista? *)
198+
let ley_impl3 (p q : Type) : no (p -> q) -> yy p (no q) =
199+
admit()
200+
201+
(* Ejercicio. ¿Se puede en lógica intuicionista? *)
202+
let ley_impl4 (p q : Type) : yy p (no q) -> no (p -> q) =
203+
admit()
204+
205+
(* Tipos para axiomas clásicos *)
206+
type eliminacion_doble_neg = (#a:Type) -> no (no a) -> a
207+
type tercero_excluido = (a:Type) -> oo a (no a)
208+
209+
(* Ejercicio *)
210+
let lte_implica_edn (lte : tercero_excluido) (#a:Type) : eliminacion_doble_neg =
211+
admit()
212+
213+
(* Ejercicio. ¡Difícil! *)
214+
let edn_implica_lte (edn : eliminacion_doble_neg) (#a:Type) : oo a (no a) =
215+
admit()
216+
217+
(* Ejercicio: ¿la ley de Peirce es intuicionista o clásica?
218+
Demuestrelá sin axiomas para demostrar que es intuicionista,
219+
o demuestre que implica el tercero excluido para demostrar que
220+
es clásica. *)
221+
222+
type peirce = (#a:Type) -> (#b:Type) -> ((a -> b) -> a) -> a
223+
224+
let lte_implica_peirce (lte : tercero_excluido) : peirce =
225+
admit()
226+
227+
let peirce_implica_lte (pp : peirce) : tercero_excluido =
228+
admit()

0 commit comments

Comments
 (0)