(*** Completeness results *)
Fact bic_PUSH_Zero_inv p i x w s st :
(i,PUSH x Zero::nil) <sc P
-> w#>(reg x) = stack_enc s
-> w#>tmp1 = 0
-> w#>tmp2 = 0
-> out_code (fst st) Q
-> Q // (lnk i,w) -[p]-> st
-> exists q, q < p /\ Q // (lnk (1+i), w[(stack_enc (Zero::s))/reg x]) -[q]-> st.
Fact bic_PUSH_One_inv p i x w s st :
(i,PUSH x One::nil) <sc P
-> w#>(reg x) = stack_enc s
-> w#>tmp1 = 0
-> w#>tmp2 = 0
-> out_code (fst st) Q
-> Q // (lnk i,w) -[p]-> st
-> exists q, q < p /\ Q // (lnk (1+i), w[(stack_enc (One::s))/reg x]) -[q]-> st.
Fact bic_POP_void_inv p i x j k w st :
(i,POP x j k::nil) <sc P
-> w#>(reg x) = stack_enc nil
-> w#>tmp1 = 0
-> w#>tmp2 = 0
-> out_code (fst st) Q
-> Q // (lnk i,w) -[p]-> st
-> exists q, q < p /\ Q // (lnk k,w) -[q]-> st.
Fact bic_POP_One_inv p i x j k w s st :
(i,POP x j k::nil) <sc P
-> w#>(reg x) = stack_enc (One::s)
-> w#>tmp1 = 0
-> w#>tmp2 = 0
-> out_code (fst st) Q
-> Q // (lnk i,w) -[p]-> st
-> exists q, q < p /\ Q // (lnk (1+i), w[(stack_enc s)/reg x]) -[q]-> st.
Fact bic_POP_Zero_inv p i x j k w s st :
(i,POP x j k::nil) <sc P
-> w#>(reg x) = stack_enc (Zero::s)
-> w#>tmp1 = 0
-> w#>tmp2 = 0
-> out_code (fst st) Q
-> Q // (lnk i,w) -[p]-> st
-> exists q, q < p /\ Q // (lnk j, w[(stack_enc s)/reg x]) -[q]-> st.

(* Specifications: *)
Lemma bsm_instr_compiler_complete p st1 w1 w3 :
bsm_state_enc (snd st1) (snd w1)
-> lnk (fst st1) = fst w1
-> in_code (fst st1) P
-> out_code (fst w3) Q
-> Q // w1 -[p]-> w3
-> exists q st2 w2, bsm_state_enc (snd st2) (snd w2)
/\ lnk (fst st2) = fst w2
/\ P /BSM/ st1 ->> st2
/\ Q // w2 -[q]-> w3
/\ q < p.
Theorem bsm_compiler_complete : forall st1 iv1 iv3,
bsm_state_enc (snd st1) (snd iv1)
-> lnk (fst st1) = fst iv1
-> out_code (fst iv3) Q
-> Q // iv1 ->> iv3
-> exists st2 iv2,
bsm_state_enc (snd st2) (snd iv2)
/\ lnk (fst st2) = fst iv2
/\ out_code (fst st2) P
/\ P /BSM/ st1 ->> st2
/\ Q // iv2 ->> iv3.