@@ -316,8 +316,82 @@ proof. by rewrite bs2int_cat bs2int_nseq_false size_nseq. qed.
316316lemma bs2int_pow2 K N :
317317 bs2int (nseq K false ++ true :: nseq N false ) = 2 ^ max 0 K.
318318proof. by rewrite bs2int_mulr_pow2 bs2int1. qed.
319- end BS2Int.
320319
320+ lemma int2bs_strikeE (l n : int ) :
321+ let k = index false (int2bs (l+1 ) n) in
322+
323+ 0 <= l
324+ => 0 <= n < 2^l
325+ => int2bs (l+1 ) n = nseq k true ++ false :: drop (k+1 ) (int2bs (l+1 ) n).
326+ proof.
327+ move=> k ??; have ge0_k: 0 <= k by apply: index_ge0.
328+ have le_kl: k <= l.
329+ - have: (nth witness (int2bs (l+1 ) n) l) \in int2bs (l+1 ) n.
330+ - by rewrite mem_nth size_int2bs /#.
331+ rewrite {2 }/int2bs nth_mkseq 1 :/# /=.
332+ by rewrite pdiv_small // = -index_mem size_int2bs /#.
333+ rewrite (@int2bs_cat k) 1:/#; congr.
334+ - rewrite &(eq_from_nth witness) !(size_int2bs, size_nseq) // .
335+ move=> i; rewrite ler_maxr // => rgi; rewrite nth_nseq //.
336+ have := before_index witness false (int2bs (l+1 ) n) i // .
337+ by rewrite !nth_mkseq ~-1:/# /= => /negbFE ->.
338+ rewrite drop_cat size_int2bs ifF 1 :/# ler_maxr // .
339+ rewrite [k+1 -k]addrAC /= int2bs_cons 1 :/# /= drop0 /=.
340+ have := nth_index witness false (int2bs (l+1 ) n) _.
341+ - by rewrite -index_mem size_int2bs // #.
342+ by rewrite -/k nth_mkseq 1:/# /= => ->.
343+ qed.
344+
345+ lemma int2bs_strike_succE (l n : int ) :
346+ let k = index false (int2bs (l+1 ) n) in
347+
348+ 0 <= l
349+ => 0 <= n < 2^l
350+ => int2bs (l+1 ) (n + 1 )
351+ = nseq k false ++ true :: drop (k + 1 ) (int2bs (l+1 ) n).
352+ proof.
353+ move=> k ??; have ge0_k: 0 <= k by apply: index_ge0.
354+ have le_kl: k <= l.
355+ - have: (nth witness (int2bs (l+1 ) n) l) \in int2bs (l+1 ) n.
356+ - by rewrite mem_nth size_int2bs /#.
357+ rewrite {2 }/int2bs nth_mkseq 1 :/# /=.
358+ by rewrite pdiv_small // = -index_mem size_int2bs /#.
359+ have [q nE]: exists q, n = q * 2 ^k + (2 ^k - 1 ).
360+ - exists (n %/ (2 ^k)); rewrite {1 }[n](@divz_eq _ (2 ^k)); congr.
361+ have := int2bsK l n // //.
362+ rewrite (@int2bs_cat k) // bs2int_cat size_int2bs ler_maxr //.
363+ move/(congr1 (fun x => x %% 2 ^k)) => /=.
364+ rewrite [2^k*_]mulrC modzMDr => <-; rewrite pmod_small.
365+ - have h := bs2int_le2Xs (int2bs k n).
366+ rewrite bs2int_ge0 /= (@ltr_le_trans _ _ _ h).
367+ by rewrite size_int2bs /#.
368+ suff ->: int2bs k n = nseq k true by rewrite bs2int_nseq_true.
369+ apply/(eq_from_nth witness); first by rewrite size_nseq size_int2bs.
370+ move=> i; rewrite size_int2bs ler_maxr // => rgi.
371+ rewrite nth_nseq // = nth_mkseq //=.
372+ have := before_index witness false (int2bs (l+1 ) n) i rgi.
373+ by rewrite nth_mkseq 1:/# /= => /negbFE ->.
374+ have oddq: !odd q.
375+ - rewrite oddPn (_ : q %% 2 = (n %/ 2 ^k) %% 2).
376+ - rewrite nE divzMDl 1:expf_eq0 // pdiv_small //=.
377+ by smt(expr_gt0).
378+ have ->: (n %/ 2 ^k %% 2 = 0 ) = !(nth witness (int2bs (l+1 ) n) k).
379+ - by rewrite nth_mkseq 1:/#.
380+ by rewrite nth_index // -index_mem -/k size_int2bs /#.
381+ have ->: n + 1 = (q + 1 ) * 2^k by rewrite nE #ring.
382+ rewrite (@int2bs_cat k) 1:/# mulzK 1 :expf_eq0 // .
383+ rewrite -int2bs_mod modzMl int2bs0 addrAC int2bs_cons 1 :/# /=.
384+ rewrite dvdzE -oddP oddS oddq /=; do 2 ! congr.
385+ rewrite (@int2bs_cat (k+1 ) (l+1 )) 1:/#.
386+ rewrite (_ : _ - (k+1 ) = l - k) 1:#ring.
387+ rewrite drop_cat_le size_int2bs ler_maxr 1 :/# /=.
388+ rewrite drop_oversize ?size_int2bs 1 :/# /=; congr.
389+ rewrite exprSr // divz_mul 1:expr_ge0 // nE.
390+ rewrite divzMDl 1 :expf_eq0 // .
391+ rewrite [_ %/ 2 ^k]pdiv_small /=; first smt (expr_gt0).
392+ by rewrite divzDl // = dvdzE -oddPn.
393+ qed.
394+ end BS2Int.
321395
322396(* -------------------------------------------------------------------- *)
323397theory BitReverse.
0 commit comments