Add experimental formalization of (inefficient) solution.
This commit is contained in:
parent
6ecae2b5bf
commit
f53c65fb0d
110
day8.v
110
day8.v
|
@ -41,13 +41,17 @@ Module DayEight (Import M:Int).
|
||||||
Definition indices (n : nat) := VectorDef.t (fin n) n.
|
Definition indices (n : nat) := VectorDef.t (fin n) n.
|
||||||
|
|
||||||
(* Change a jump to a nop, or a nop to a jump. *)
|
(* Change a jump to a nop, or a nop to a jump. *)
|
||||||
Definition replace (i : inst) : inst :=
|
Definition swap (i : inst) : inst :=
|
||||||
match i with
|
match i with
|
||||||
| (add, t) => (add, t)
|
| (add, t) => (add, t)
|
||||||
| (nop, t) => (jmp, t)
|
| (nop, t) => (jmp, t)
|
||||||
| (jmp, t) => (nop, t)
|
| (jmp, t) => (nop, t)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Inductive swappable : inst -> Prop :=
|
||||||
|
| swap_nop : forall t, swappable (nop, t)
|
||||||
|
| swap_jmp : forall t, swappable (jmp, t).
|
||||||
|
|
||||||
(* Compute the destination jump index, an integer. *)
|
(* Compute the destination jump index, an integer. *)
|
||||||
Definition jump_t {n} (pc : fin n) (off : t) : t :=
|
Definition jump_t {n} (pc : fin n) (off : t) : t :=
|
||||||
M.add (nat_to_t (proj1_sig (to_nat pc))) off.
|
M.add (nat_to_t (proj1_sig (to_nat pc))) off.
|
||||||
|
@ -96,20 +100,14 @@ Module DayEight (Import M:Int).
|
||||||
(* One modification: we really want to use 'allowed' addresses,
|
(* One modification: we really want to use 'allowed' addresses,
|
||||||
a set that shrinks as the program continues, rather than 'visited'
|
a set that shrinks as the program continues, rather than 'visited'
|
||||||
addresses, a set that increases as the program continues. *)
|
addresses, a set that increases as the program continues. *)
|
||||||
Inductive step_noswap {n} : input n -> state n -> state n -> Prop :=
|
Inductive step_noswap {n} : inst -> (fin n * t) -> (fin (S n) * t) -> Prop :=
|
||||||
| step_noswap_add : forall inp pc' v acc t,
|
| step_noswap_add : forall pc acc t,
|
||||||
nth inp pc' = (add, t) ->
|
step_noswap (add, t) (pc, acc) (FS pc, M.add acc t)
|
||||||
set_In pc' v ->
|
| step_noswap_nop : forall pc acc t,
|
||||||
step_noswap inp (weaken_one pc', v, acc) (FS pc', set_remove Fin.eq_dec pc' v, M.add acc t)
|
step_noswap (nop, t) (pc, acc) (FS pc, acc)
|
||||||
| step_noswap_nop : forall inp pc' v acc t,
|
| step_noswap_jmp : forall pc pc' acc t,
|
||||||
nth inp pc' = (nop, t) ->
|
valid_jump_t pc t = Some pc' ->
|
||||||
set_In pc' v ->
|
step_noswap (jmp, t) (pc, acc) (pc', acc).
|
||||||
step_noswap inp (weaken_one pc', v, acc) (FS pc', set_remove Fin.eq_dec pc' v, acc)
|
|
||||||
| step_noswap_jmp : forall inp pc' pc'' v acc t,
|
|
||||||
nth inp pc' = (jmp, t) ->
|
|
||||||
set_In pc' v ->
|
|
||||||
valid_jump_t pc' t = Some pc'' ->
|
|
||||||
step_noswap inp (weaken_one pc', v, acc) (pc'', set_remove Fin.eq_dec pc' v, acc).
|
|
||||||
|
|
||||||
Inductive done {n} : input n -> state n -> Prop :=
|
Inductive done {n} : input n -> state n -> Prop :=
|
||||||
| done_prog : forall inp v acc, done inp (nat_to_fin n, v, acc).
|
| done_prog : forall inp v acc, done inp (nat_to_fin n, v, acc).
|
||||||
|
@ -121,8 +119,35 @@ Module DayEight (Import M:Int).
|
||||||
Inductive run_noswap {n} : input n -> state n -> state n -> Prop :=
|
Inductive run_noswap {n} : input n -> state n -> state n -> Prop :=
|
||||||
| run_noswap_ok : forall inp st, done inp st -> run_noswap inp st st
|
| run_noswap_ok : forall inp st, done inp st -> run_noswap inp st st
|
||||||
| run_noswap_fail : forall inp st, stuck inp st -> run_noswap inp st st
|
| run_noswap_fail : forall inp st, stuck inp st -> run_noswap inp st st
|
||||||
| run_noswap_trans : forall inp st st' st'',
|
| run_noswap_trans : forall inp pc pc' v acc acc' st',
|
||||||
step_noswap inp st st' -> run_noswap inp st' st'' -> run_noswap inp st st''.
|
set_In pc v ->
|
||||||
|
step_noswap (nth inp pc) (pc, acc) (pc', acc') ->
|
||||||
|
run_noswap inp (pc', set_remove Fin.eq_dec pc v, acc') st' ->
|
||||||
|
run_noswap inp (weaken_one pc, v, acc) st'.
|
||||||
|
|
||||||
|
Inductive run_swap {n} : input n -> state n -> state n -> Prop :=
|
||||||
|
| run_swap_normal : forall inp pc pc' v acc acc' st',
|
||||||
|
set_In pc v ->
|
||||||
|
~ swappable (nth inp pc) ->
|
||||||
|
step_noswap (nth inp pc) (pc, acc) (pc', acc') ->
|
||||||
|
run_swap inp (pc', set_remove Fin.eq_dec pc v, acc') st' ->
|
||||||
|
run_swap inp (weaken_one pc, v, acc) st'
|
||||||
|
| run_swap_swapped_ok : forall inp pc pc' v acc acc' st',
|
||||||
|
set_In pc v ->
|
||||||
|
swappable (nth inp pc) ->
|
||||||
|
step_noswap (swap (nth inp pc)) (pc, acc) (pc', acc') ->
|
||||||
|
run_noswap inp (pc', set_remove Fin.eq_dec pc v, acc') st' ->
|
||||||
|
done inp st' ->
|
||||||
|
run_swap inp (weaken_one pc, v, acc) st'
|
||||||
|
| run_swap_swapped_next : forall inp pc pc'w pc'n v acc acc'w acc'n st'w st'n,
|
||||||
|
set_In pc v ->
|
||||||
|
swappable (nth inp pc) ->
|
||||||
|
step_noswap (swap (nth inp pc)) (pc, acc) (pc'w, acc'w) ->
|
||||||
|
run_noswap inp (pc'w, set_remove Fin.eq_dec pc v, acc'w) st'w ->
|
||||||
|
stuck inp st'w ->
|
||||||
|
step_noswap (nth inp pc) (pc, acc) (pc'n, acc'n) ->
|
||||||
|
run_swap inp (pc'n, set_remove Fin.eq_dec pc v, acc'n) st'n ->
|
||||||
|
run_swap inp (weaken_one pc, v, acc) st'n.
|
||||||
|
|
||||||
Inductive valid_inst {n} : inst -> fin n -> Prop :=
|
Inductive valid_inst {n} : inst -> fin n -> Prop :=
|
||||||
| valid_inst_add : forall t f, valid_inst (add, t) f
|
| valid_inst_add : forall t f, valid_inst (add, t) f
|
||||||
|
@ -140,19 +165,16 @@ Module DayEight (Import M:Int).
|
||||||
Variable inp : input n.
|
Variable inp : input n.
|
||||||
Hypothesis Hv : valid_input inp.
|
Hypothesis Hv : valid_input inp.
|
||||||
|
|
||||||
(* If the current address, which is not the end of the array, is
|
Theorem valid_input_can_step : forall pc acc, exists pc' acc',
|
||||||
present in the "allowed" set, the program can continue. *)
|
step_noswap (nth inp pc) (pc, acc) (pc', acc').
|
||||||
Lemma step_if_possible : forall pcs v acc,
|
|
||||||
set_In pcs v ->
|
|
||||||
exists pc' acc', step_noswap inp (weaken_one pcs, v, acc) (pc', set_remove Fin.eq_dec pcs v, acc').
|
|
||||||
Proof.
|
Proof.
|
||||||
intros pcs v acc Hin.
|
intros pc acc.
|
||||||
remember (nth inp pcs) as instr. destruct instr as [op t]. destruct op.
|
destruct (nth inp pc) eqn:Hop.
|
||||||
+ exists (FS pcs). exists (M.add acc t). apply step_noswap_add; auto.
|
destruct o.
|
||||||
+ exists (FS pcs). exists acc. apply step_noswap_nop with t; auto.
|
- exists (FS pc). exists (M.add acc t0). apply step_noswap_add.
|
||||||
+ unfold valid_input in Hv. specialize (Hv pcs).
|
- exists (FS pc). exists acc. eapply step_noswap_nop.
|
||||||
rewrite <- Heqinstr in Hv. inversion Hv; subst.
|
- specialize (Hv pc). rewrite Hop in Hv. inversion Hv; subst.
|
||||||
exists f'. exists acc. apply step_noswap_jmp with t; auto.
|
exists f'. exists acc. eapply step_noswap_jmp. apply H0.
|
||||||
Qed.
|
Qed.
|
||||||
|
|
||||||
(* A program is either done, stuck (at an invalid/visited address), or can step. *)
|
(* A program is either done, stuck (at an invalid/visited address), or can step. *)
|
||||||
|
@ -161,7 +183,7 @@ Module DayEight (Import M:Int).
|
||||||
(exists pcs, pc = weaken_one pcs /\
|
(exists pcs, pc = weaken_one pcs /\
|
||||||
((~ set_In pcs v /\ stuck inp (pc, v, acc)) \/
|
((~ set_In pcs v /\ stuck inp (pc, v, acc)) \/
|
||||||
(exists pc' acc', set_In pcs v /\
|
(exists pc' acc', set_In pcs v /\
|
||||||
step_noswap inp (pc, v, acc) (pc', set_remove Fin.eq_dec pcs v, acc')))).
|
step_noswap (nth inp pcs) (pcs, acc) (pc', acc')))).
|
||||||
Proof.
|
Proof.
|
||||||
intros pc v acc.
|
intros pc v acc.
|
||||||
(* Have we reached the end? *)
|
(* Have we reached the end? *)
|
||||||
|
@ -174,8 +196,8 @@ Module DayEight (Import M:Int).
|
||||||
destruct (set_In_dec Fin.eq_dec pcs v).
|
destruct (set_In_dec Fin.eq_dec pcs v).
|
||||||
- (* It is. *)
|
- (* It is. *)
|
||||||
right.
|
right.
|
||||||
destruct (step_if_possible pcs v acc) as [pc' [acc' Hstep]]; auto.
|
destruct (valid_input_can_step pcs acc) as [pc' [acc' Hstep]].
|
||||||
exists pc'. exists acc'. split; auto.
|
exists pc'; exists acc'; auto.
|
||||||
- (* It is not. *)
|
- (* It is not. *)
|
||||||
left. split; auto. apply stuck_prog; auto.
|
left. split; auto. apply stuck_prog; auto.
|
||||||
Qed.
|
Qed.
|
||||||
|
@ -186,30 +208,19 @@ Module DayEight (Import M:Int).
|
||||||
{ measure (length v) }:
|
{ measure (length v) }:
|
||||||
(exists pc', run_noswap inp (pc, v, acc) pc') :=
|
(exists pc', run_noswap inp (pc, v, acc) pc') :=
|
||||||
match valid_input_progress pc v acc with
|
match valid_input_progress pc v acc with
|
||||||
| or_introl (conj Heq Hdone) =>
|
| or_introl (conj Heq Hdone) => _
|
||||||
inhabited_sig_to_exists
|
|
||||||
(inhabits
|
|
||||||
(@exist (state n)
|
|
||||||
(fun x => run_noswap inp (pc, v, acc) x) (pc, v, acc) (run_noswap_ok _ _ Hdone)))
|
|
||||||
| or_intror (ex_intro _ pcs (conj Hw w)) =>
|
| or_intror (ex_intro _ pcs (conj Hw w)) =>
|
||||||
match w with
|
match w with
|
||||||
| or_introl (conj Hnin Hstuck) =>
|
| or_introl (conj Hnin Hstuck) => _
|
||||||
inhabited_sig_to_exists
|
|
||||||
(inhabits
|
|
||||||
(@exist (state n)
|
|
||||||
(fun x => run_noswap inp (pc, v, acc) x) (pc, v, acc) (run_noswap_fail _ _ Hstuck)))
|
|
||||||
| or_intror (ex_intro _ pc' (ex_intro _ acc' (conj Hin Hst))) =>
|
| or_intror (ex_intro _ pc' (ex_intro _ acc' (conj Hin Hst))) =>
|
||||||
match valid_input_terminates pc' (set_remove Fin.eq_dec pcs v) acc' (set_remove_nodup Fin.eq_dec pcs Hnd) with
|
match valid_input_terminates pc' (set_remove Fin.eq_dec pcs v) acc' (set_remove_nodup Fin.eq_dec pcs Hnd) with
|
||||||
| ex_intro _ pc'' Hrun =>
|
| ex_intro _ pc'' Hrun => _
|
||||||
inhabited_sig_to_exists
|
|
||||||
(inhabits
|
|
||||||
(@exist (state n)
|
|
||||||
(fun x => run_noswap inp (pc, v, acc) x) pc''
|
|
||||||
(run_noswap_trans _ _ (pc', set_remove Fin.eq_dec pcs v, acc') _ Hst Hrun)))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
Obligation 1.
|
Obligation 1. eexists. apply run_noswap_ok. assumption. Qed.
|
||||||
|
Obligation 2. eexists. apply run_noswap_fail. assumption. Qed.
|
||||||
|
Obligation 3.
|
||||||
clear Heq_anonymous. clear valid_input_terminates. clear Hst.
|
clear Heq_anonymous. clear valid_input_terminates. clear Hst.
|
||||||
induction v.
|
induction v.
|
||||||
- inversion Hin.
|
- inversion Hin.
|
||||||
|
@ -220,5 +231,6 @@ Module DayEight (Import M:Int).
|
||||||
specialize (IHv H2 H).
|
specialize (IHv H2 H).
|
||||||
simpl. rewrite Heq_dec. simpl. lia.
|
simpl. rewrite Heq_dec. simpl. lia.
|
||||||
Qed.
|
Qed.
|
||||||
|
Obligation 4. eexists. eapply run_noswap_trans; auto. apply Hst. apply Hrun. Qed.
|
||||||
End ValidInput.
|
End ValidInput.
|
||||||
End DayEight.
|
End DayEight.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user