F* language preview
1. A verified factorial
let rec, a val signature, and a Lemma with requires/ensures
horizon-dark
(* factorial and a proof that it's always at least 1 *)
let rec factorial (n:nat) : nat =
if n = 0 then 1 else n * factorial (n - 1)
val factorial_pos : n:nat -> Lemma (requires True) (ensures (factorial n >= 1))
let rec factorial_pos n =
if n = 0 then () else factorial_pos (n - 1) atom-one-dark
(* factorial and a proof that it's always at least 1 *)
let rec factorial (n:nat) : nat =
if n = 0 then 1 else n * factorial (n - 1)
val factorial_pos : n:nat -> Lemma (requires True) (ensures (factorial n >= 1))
let rec factorial_pos n =
if n = 0 then () else factorial_pos (n - 1) github-dark
(* factorial and a proof that it's always at least 1 *)
let rec factorial (n:nat) : nat =
if n = 0 then 1 else n * factorial (n - 1)
val factorial_pos : n:nat -> Lemma (requires True) (ensures (factorial n >= 1))
let rec factorial_pos n =
if n = 0 then () else factorial_pos (n - 1) dracula
(* factorial and a proof that it's always at least 1 *)
let rec factorial (n:nat) : nat =
if n = 0 then 1 else n * factorial (n - 1)
val factorial_pos : n:nat -> Lemma (requires True) (ensures (factorial n >= 1))
let rec factorial_pos n =
if n = 0 then () else factorial_pos (n - 1) nord
(* factorial and a proof that it's always at least 1 *)
let rec factorial (n:nat) : nat =
if n = 0 then 1 else n * factorial (n - 1)
val factorial_pos : n:nat -> Lemma (requires True) (ensures (factorial n >= 1))
let rec factorial_pos n =
if n = 0 then () else factorial_pos (n - 1) github
(* factorial and a proof that it's always at least 1 *)
let rec factorial (n:nat) : nat =
if n = 0 then 1 else n * factorial (n - 1)
val factorial_pos : n:nat -> Lemma (requires True) (ensures (factorial n >= 1))
let rec factorial_pos n =
if n = 0 then () else factorial_pos (n - 1) 2. A noeq record with an effectful field
noeq type, the Tot effect, and inline_for_extraction
horizon-dark
noeq type stream (a:Type) = {
head: a;
tail: unit -> Tot (stream a);
}
inline_for_extraction
let rec nth (#a:Type) (s:stream a) (n:nat) : Tot a =
if n = 0 then s.head else nth (s.tail ()) (n - 1) atom-one-dark
noeq type stream (a:Type) = {
head: a;
tail: unit -> Tot (stream a);
}
inline_for_extraction
let rec nth (#a:Type) (s:stream a) (n:nat) : Tot a =
if n = 0 then s.head else nth (s.tail ()) (n - 1) github-dark
noeq type stream (a:Type) = {
head: a;
tail: unit -> Tot (stream a);
}
inline_for_extraction
let rec nth (#a:Type) (s:stream a) (n:nat) : Tot a =
if n = 0 then s.head else nth (s.tail ()) (n - 1) dracula
noeq type stream (a:Type) = {
head: a;
tail: unit -> Tot (stream a);
}
inline_for_extraction
let rec nth (#a:Type) (s:stream a) (n:nat) : Tot a =
if n = 0 then s.head else nth (s.tail ()) (n - 1) nord
noeq type stream (a:Type) = {
head: a;
tail: unit -> Tot (stream a);
}
inline_for_extraction
let rec nth (#a:Type) (s:stream a) (n:nat) : Tot a =
if n = 0 then s.head else nth (s.tail ()) (n - 1) github
noeq type stream (a:Type) = {
head: a;
tail: unit -> Tot (stream a);
}
inline_for_extraction
let rec nth (#a:Type) (s:stream a) (n:nat) : Tot a =
if n = 0 then s.head else nth (s.tail ()) (n - 1) 3. A ghost lemma about list length
ghost, GTot, and unfold in a small proof
horizon-dark
unfold let rec length (#a:Type) (l:list a) : GTot nat =
match l with
| [] -> 0
| _ :: tl -> 1 + length tl
val append_length : #a:Type -> l1:list a -> l2:list a ->
Lemma (ensures (length (l1 @ l2) = length l1 + length l2))
let rec append_length l1 l2 =
match l1 with
| [] -> ()
| _ :: tl -> append_length tl l2 atom-one-dark
unfold let rec length (#a:Type) (l:list a) : GTot nat =
match l with
| [] -> 0
| _ :: tl -> 1 + length tl
val append_length : #a:Type -> l1:list a -> l2:list a ->
Lemma (ensures (length (l1 @ l2) = length l1 + length l2))
let rec append_length l1 l2 =
match l1 with
| [] -> ()
| _ :: tl -> append_length tl l2 github-dark
unfold let rec length (#a:Type) (l:list a) : GTot nat =
match l with
| [] -> 0
| _ :: tl -> 1 + length tl
val append_length : #a:Type -> l1:list a -> l2:list a ->
Lemma (ensures (length (l1 @ l2) = length l1 + length l2))
let rec append_length l1 l2 =
match l1 with
| [] -> ()
| _ :: tl -> append_length tl l2 dracula
unfold let rec length (#a:Type) (l:list a) : GTot nat =
match l with
| [] -> 0
| _ :: tl -> 1 + length tl
val append_length : #a:Type -> l1:list a -> l2:list a ->
Lemma (ensures (length (l1 @ l2) = length l1 + length l2))
let rec append_length l1 l2 =
match l1 with
| [] -> ()
| _ :: tl -> append_length tl l2 nord
unfold let rec length (#a:Type) (l:list a) : GTot nat =
match l with
| [] -> 0
| _ :: tl -> 1 + length tl
val append_length : #a:Type -> l1:list a -> l2:list a ->
Lemma (ensures (length (l1 @ l2) = length l1 + length l2))
let rec append_length l1 l2 =
match l1 with
| [] -> ()
| _ :: tl -> append_length tl l2 github
unfold let rec length (#a:Type) (l:list a) : GTot nat =
match l with
| [] -> 0
| _ :: tl -> 1 + length tl
val append_length : #a:Type -> l1:list a -> l2:list a ->
Lemma (ensures (length (l1 @ l2) = length l1 + length l2))
let rec append_length l1 l2 =
match l1 with
| [] -> ()
| _ :: tl -> append_length tl l2