Skip to content
Snippets Groups Projects
heap_lang_tactics.v 2.45 KiB
Newer Older
Require Export barrier.heap_lang.
Require Import prelude.fin_maps.
Import heap_lang.

Ltac inv_step :=
  repeat match goal with
  | _ => progress simplify_map_equality' (* simplify memory stuff *)
  | H : to_val _ = Some _ |- _ => apply of_to_val in H
  | H : context [to_val (of_val _)] |- _ => rewrite to_of_val in H
  | H : prim_step _ _ _ _ _ |- _ => destruct H; subst
  | H : _ = fill ?K ?e |- _ =>
     destruct K as [|[]];
     simpl in H; first [subst e|discriminate H|injection' H]
     (* ensure that we make progress for each subgoal *)
  | H : head_step ?e _ _ _ _, Hv : of_val ?v = fill ?K ?e |- _ =>
    apply values_head_stuck, (fill_not_val K) in H;
    by rewrite -Hv to_of_val in H (* maybe use a helper lemma here? *)
  | H : head_step ?e _ _ _ _ |- _ =>
     try (is_var e; fail 1); (* inversion yields many goals if e is a variable
     and can thus better be avoided. *)
     inversion H; subst; clear H
  end.

Ltac reshape_expr e tac :=
  let rec go K e :=
  match e with
  | _ => tac (reverse K) e
  | App ?e1 ?e2 =>
     lazymatch e1 with
     | of_val ?v1 => go (AppRCtx v1 :: K) e2 | _ => go (AppLCtx e2 :: K) e1
     end
  | Plus ?e1 ?e2 =>
     lazymatch e1 with
     | of_val ?v1 => go (PlusRCtx v1 :: K) e2 | _ => go (PlusLCtx e2 :: K) e1
     end
  | Le ?e1 ?e2 =>
     lazymatch e1 with
     | of_val ?v1 => go (LeRCtx v1 :: K) e2 | _ => go (LeLCtx e2 :: K) e1
     end
  | Pair ?e1 ?e2 =>
     lazymatch e1 with
     | of_val ?v1 => go (PairRCtx v1 :: K) e2 | _ => go (PairLCtx e2 :: K) e1
     end
  | Fst ?e => go (FstCtx :: K) e
  | Snd ?e => go (SndCtx :: K) e
  | InjL ?e => go (InjLCtx :: K) e
  | InjR ?e => go (InjRCtx :: K) e
  | Case ?e0 ?e1 ?e2 => go (CaseCtx e1 e2 :: K) e0
  | Alloc ?e => go (AllocCtx :: K) e
  | Load ?e => go (LoadCtx :: K) e
  | Store ?e1 ?e2 => go (StoreLCtx e2 :: K) e1 || go (StoreRCtx e1 :: K) e2
  | Cas ?e0 ?e1 ?e2 =>
     lazymatch e0 with
     | of_val ?v0 =>
        lazymatch e1 with
        | of_val ?v1 => go (CasRCtx v0 v1 :: K) e2
        | _ => go (CasMCtx v0 e2 :: K) e1
        end
     | _ => go (CasLCtx e1 e2 :: K) e0
     end
  end in go (@nil ectx_item) e.

Ltac do_step tac :=
  try match goal with |- language.reducible _ _ => eexists _, _, _ end;
  simpl;
  match goal with
  | |- prim_step ?e1 ?σ1 ?e2 ?σ2 ?ef =>
     reshape_expr e1 ltac:(fun K e1' =>
       eapply Ectx_step with K e1' _; [reflexivity|reflexivity|];
       first [apply alloc_fresh|econstructor];
       rewrite ?to_of_val; tac; fail)