include "common/IO.ma". include "common/SmallstepExec.ma". include "arithmetics/nat.ma". (* Functions to allow programs to be executed up to some number of steps, given a predetermined set of input values. Note that we throw away the state if we stop at a continuation - it can be too large to work with. *) definition get_input : ∀o:io_out. eventval → res (io_in o) ≝ λo,ev. match io_in_typ o return λt. res (eventval_type t) with [ ASTint sz _ ⇒ match ev with [ EVint sz' i ⇒ intsize_eq_elim ? sz' sz ? i (λi.OK ? i) (Error ? (msg IllTypedEvent)) | _ ⇒ Error ? (msg IllTypedEvent) ] | ASTfloat _ ⇒ match ev with [ EVfloat f ⇒ OK ? f | _ ⇒ Error ? (msg IllTypedEvent) ] | ASTptr ⇒ Error ? (msg IllTypedEvent) ]. inductive snapshot (state:Type[0]) : Type[0] ≝ | running : trace → state → snapshot state | finished : trace → int → state → snapshot state | input_exhausted : trace → snapshot state. axiom StoppedMidIO : String. let rec up_to_nth_step (n:nat) (state:Type[0]) (input:list eventval) (e:execution state io_out io_in) (t:trace) : res (snapshot state) ≝ match n with [ O ⇒ match e with [ e_step tr s _ ⇒ OK ? (running ? (t⧺tr) s) | e_stop tr r m ⇒ OK ? (finished ? (t⧺tr) r m) | e_interact o k ⇒ Error ? (msg StoppedMidIO) | e_wrong m ⇒ Error ? m ] | S m ⇒ match e with [ e_step tr s e' ⇒ up_to_nth_step m state input e' (t⧺tr) | e_stop tr r m ⇒ OK ? (finished ? (t⧺tr) r m) | e_interact o k ⇒ match input with [ nil ⇒ OK ? (input_exhausted ? t) | cons h tl ⇒ do i ← get_input o h; up_to_nth_step m state tl (k i) t ] | e_wrong m ⇒ Error ? m ] ]. definition exec_up_to : ∀fx:fullexec io_out io_in. ∀p:program ?? fx. nat → list eventval → res (snapshot (state ?? fx (make_global … p))) ≝ λfx,p,n,i. up_to_nth_step n ? i (exec_inf ?? fx p) E0. (* A version of exec_up_to that reports the state prior to failure. *) inductive snapshot' (state:Type[0]) : Type[0] ≝ | running' : trace → state → snapshot' state | finished' : nat → trace → int → state → snapshot' state | input_exhausted' : trace → snapshot' state | failed' : errmsg → nat → state → snapshot' state | init_state_fail' : errmsg → snapshot' state. let rec up_to_nth_step' (n:nat) (total:nat) (state:Type[0]) (input:list eventval) (e:execution state io_out io_in) (prev:state) (t:trace) : snapshot' state ≝ match n with [ O ⇒ match e with [ e_step tr s _ ⇒ running' ? (t⧺tr) s | e_stop tr r m ⇒ finished' ? total (t⧺tr) r m | e_interact o k ⇒ failed' ? (msg StoppedMidIO) total prev | e_wrong m ⇒ failed' ? m total prev ] | S m ⇒ match e with [ e_step tr s e' ⇒ up_to_nth_step' m total state input e' s (t⧺tr) | e_stop tr r m ⇒ finished' ? (minus total n) (t⧺tr) r m | e_interact o k ⇒ match input with [ nil ⇒ input_exhausted' ? t | cons h tl ⇒ match get_input o h with [ OK i ⇒ up_to_nth_step' m total state tl (k i) prev t | Error m ⇒ failed' ? m (minus total n) prev ] ] | e_wrong m ⇒ failed' ? m (minus total n) prev ] ]. definition exec_up_to' : ∀fx:fullexec io_out io_in. ∀p:program ?? fx. nat → list eventval → snapshot' (state ?? fx (make_global … p)) ≝ λfx,p,n,i. match make_initial_state ?? fx p with [ OK s ⇒ up_to_nth_step' n n (state ?? fx (make_global … p)) i (exec_inf ?? fx p) s E0 | Error m ⇒ init_state_fail' ? m ]. (* Provide an easy way to get a term in proof mode for reduction. For example, example exec: result ? (exec_up_to myprog 20 [EVint (repr 12)]). normalize (* you can examine the result here *) % qed. *) inductive result (A:Type[0]) : A → Type[0] ≝ | witness : ∀a:A. result A a. inductive finishes_with : int → ∀S.res (snapshot S) → Prop ≝ fw_ok : ∀r,S,t,s. finishes_with r S (OK ? (finished S t r s)). include "common/GenMem.ma". (* Hide the representation of memory to make displaying the results easier. *) notation < "'MEM'" with precedence 1 for @{ 'mem }. interpretation "hide memory" 'mem = (mk_mem ???).