Require Import List.
Declare Scope option_monad_scope.
Notation "'
SOME'
X <-
A '
IN'
B" := (
match A with Some X =>
B |
None =>
None end)
(
at level 200,
X name,
A at level 100,
B at level 200)
:
option_monad_scope.
Notation "'
ASSERT'
A '
IN'
B" := (
if A then B else None)
(
at level 200,
A at level 100,
B at level 200)
:
option_monad_scope.
Local Open Scope option_monad_scope.
Simple tactics for option-monad
Ltac deepest_match exp :=
match exp with
|
context f [
match ?
expr with |
_ =>
_ end] =>
ltac: (
deepest_match expr)
|
_ =>
exp
end.
Ltac autodestruct :=
let EQ :=
fresh "
EQ"
in
match goal with
| |-
context f [
match ?
expr with |
_ =>
_ end] =>
let t :=
ltac: (
deepest_match expr)
in
destruct t eqn:
EQ;
generalize EQ;
clear EQ;
congruence ||
trivial
end.
Ltac simplify_someHyp :=
match goal with
|
H:
None =
Some _ |-
_ =>
inversion H
|
H:
Some _ =
None |-
_ =>
inversion H
|
H:
false =
true |-
_ =>
inversion H
|
H:
true =
false |-
_ =>
inversion H
|
H: ?
t = ?
t |-
_ =>
clear H
|
H:
Some _ =
Some _ |-
_ =>
inversion H;
clear H;
subst
|
H:
Some _ <>
None |-
_ =>
clear H
|
H:
None <>
Some _ |-
_ =>
clear H
|
H:
true <>
false |-
_ =>
clear H
|
H:
false <>
true |-
_ =>
clear H
|
H:
_ =
Some _ |-
_ => (
try rewrite !
H in * |- *);
generalize H;
clear H
|
H:
_ =
None |-
_ => (
try rewrite !
H in * |- *);
generalize H;
clear H
|
H:
_ =
true |-
_ => (
try rewrite !
H in * |- *);
generalize H;
clear H
|
H:
_ =
false |-
_ => (
try rewrite !
H in * |- *);
generalize H;
clear H
end.
Ltac simplify_someHyps :=
repeat (
simplify_someHyp;
simpl in * |- *).
Ltac try_simplify_someHyps :=
try (
intros;
simplify_someHyps;
eauto).
Ltac simplify_option :=
repeat (
try_simplify_someHyps;
autodestruct);
try_simplify_someHyps.
Related operations
Fixpoint map_opt {
A B} (
f :
A ->
option B) (
l :
list A) :
option (
list B) :=
match l with
|
nil =>
Some nil
|
cons x xs =>
SOME y <-
f x IN
SOME ys <-
map_opt f xs IN
Some (
cons y ys)
end.
Simple lemmas
Inductive elim_SOME_someT [
A B] (
a :
option A) (
f :
A ->
option B) (
y :
B) :
Prop :=
|
Elim_SOME_someT (
x :
A) (
SOME_x :
a =
Some x) (
SOME_y :
f x =
Some y).
Lemma elim_SOME_Some [
A B] [
a :
option A] [
f :
A ->
option B] [
y :
B]:
(
SOME x <-
a IN f x) =
Some y ->
elim_SOME_someT a f y.
Proof.
autodestruct; econstructor; eauto.
Qed.