-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathCTrees.v
3682 lines (3524 loc) · 146 KB
/
CTrees.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
(** Copyright (c) 2015 Bill White **)
(** Distributed under the MIT/X11 software license **)
(** See http://www.opensource.org/licenses/mit-license.php **)
(** CTrees: Compact trees (ctrees) are representations of nonempty mtrees which
store less information. There is no ctree corresponding to an empty mtree,
so the type option (ctree n) is used when we want to allow for
the possibility of an empty tree.
If there is only one leaf beneath a node that is nonempty, then the corresponding
ctree node may be given by a leaf with the rest of the address and the
nonempty hlist (nehlist) that at that leaf.
As with mtrees, a ctree node may be a hash value summarizing the missing information
that would be below the node.
Suppose a ctree node has more than one nonempty leaf beneath it. In this case
it is possible that only the left child has nonempty leaves, only the right child
has nonempty leaves, or both children have nonempty leaves. There are three
cases for each of these. The development is similar to the one in MTrees,
falling back on results from MTrees when it is reasonable to do so.
The ctree representation can be used to determine if a transaction is supported
(see mtree_ctree_supports_tx and mtree_octree_supports_tx). A ctree
can be transformed using tx_octree_trans and this preserves approximation
of ledger functions (octree_approx_trans). The change in the sum of the asset values
of transformed ctrees corresponds to the rewards/fees of the supported transaction.
**)
Require Export MTrees.
(*** Compact representations of mtrees ***)
Fixpoint ctree (n:nat) : Type :=
match n with
| O => nehlist
| S n => sum (prod (bitseq (S n)) nehlist)
(sum hashval
(sum (ctree n)
(sum (ctree n)
(prod (ctree n) (ctree n)))))
end.
Definition ctreeL (hl:nehlist) {n} : bitseq n -> ctree n :=
match n with
| O => fun alpha => hl
| S n => fun alpha => inl (alpha,hl)
end.
Definition ctreeH (n:nat) (h:hashval) : ctree n :=
match n with
| O => inl h
| S n => inr (inl h)
end.
Definition ctreeBL {n} (Tl : ctree n) : ctree (S n) :=
inr (inr (inl Tl)).
Definition ctreeBR {n} (Tr : ctree n) : ctree (S n) :=
inr (inr (inr (inl Tr))).
Definition ctreeB {n} (Tl Tr : ctree n) : ctree (S n) :=
inr (inr (inr (inr (Tl,Tr)))).
Fixpoint ctreeLinv {n} : ctree n -> option (bitseq n * nehlist) :=
match n with
| O => fun T:ctree 0 => Some(tt,T)
| S n => fun T => match T with
| inl (alpha,hl) => Some(alpha,hl)
| inr (inr (inl Tl)) =>
match ctreeLinv Tl with
| Some(alpha,hl) => Some((false,alpha),hl)
| None => None
end
| inr (inr (inr (inl Tr))) =>
match ctreeLinv Tr with
| Some(alpha,hl) => Some((true,alpha),hl)
| None => None
end
| _ => None
end
end.
Definition ctreeHinv {n} : ctree n -> option hashval :=
match n with
| O => fun hl => match hl with
| inl h => Some(h)
| _ => None
end
| S n => fun T => match T with
| inr (inl h) => Some(h)
| _ => None
end
end.
Fixpoint ctree_mtree {n} : ctree n -> mtree n :=
match n as n' return ctree n' -> mtree n' with
| O => fun hl:ctree 0 => singlebranch_mtree hl (tt:bitseq 0)
| S n => fun T:ctree (S n) =>
match T with
| inl (alpha,hl) => singlebranch_mtree hl alpha
| inr (inl h) => mtreeH n (Some h)
| inr (inr (inl Tl)) => mtreeB (ctree_mtree Tl) (empty_mtree n)
| inr (inr (inr (inl Tr))) => mtreeB (empty_mtree n) (ctree_mtree Tr)
| inr (inr (inr (inr (Tl,Tr)))) => mtreeB (ctree_mtree Tl) (ctree_mtree Tr)
end
end.
Definition ctree_node {n} : option (ctree n) -> option (ctree n) -> option (ctree (S n)) :=
fun T1o T2o =>
match T1o,T2o with
| Some(T1),Some(T2) => Some (ctreeB T1 T2)
| Some(T1),None =>
match ctreeLinv T1 with
| Some(alpha,hl) => Some (ctreeL hl ((false,alpha):bitseq (S n)))
| None => Some (ctreeBL T1)
end
| None,Some(T2) =>
match ctreeLinv T2 with
| Some(alpha,hl) => Some (ctreeL hl ((true,alpha):bitseq (S n)))
| None => Some (ctreeBR T2)
end
| None,None => None
end.
Fixpoint mtree_octree {n} : mtree n -> option (ctree n) :=
match n with
| O => fun hl:mtree 0 =>
match hl with
| hlistN => None
| hlistH h => Some (ctreeL (inl h) (tt:bitseq 0))
| hlistC h hl => Some (ctreeL (inr (h,hl)) (tt:bitseq 0))
end
| S n => fun T:mtree (S n) =>
match T with
| inl None => None
| inl (Some h) => Some (ctreeH (S n) h)
| inr (Tl,Tr) =>
ctree_node (mtree_octree Tl) (mtree_octree Tr)
end
end.
Lemma ctreeLinv_singlebranch {n} :
forall (T:ctree n) alpha hl,
ctreeLinv T = Some (alpha, hl) ->
singlebranch_mtree hl alpha = ctree_mtree T.
induction n as [|n IH].
- simpl. intros hr [] hl. congruence.
- simpl. intros [[beta [h|[h hr]]]|[h|[Tl|[Tr|[Tl Tr]]]]] alpha hl H1.
+ inversion H1. reflexivity.
+ inversion H1. reflexivity.
+ discriminate H1.
+ destruct (ctreeLinv Tl) as [[gamma hl']|] eqn:E1.
* { inversion H1. rewrite (IH Tl).
- reflexivity.
- congruence.
}
* discriminate H1.
+ destruct (ctreeLinv Tr) as [[gamma hl']|] eqn:E1.
* { inversion H1. rewrite (IH Tr).
- reflexivity.
- congruence.
}
* discriminate H1.
+ discriminate H1.
Qed.
Definition octree_mtree {n} (T: option (ctree n)) : mtree n :=
match T with
| None => empty_mtree n
| Some T => ctree_mtree T
end.
Lemma octree_inv {n} (T:mtree n) :
mtree_normal_p T ->
octree_mtree (mtree_octree T) = T.
induction n as [|n IH].
- destruct T as [h| |h hl]; intros _. simpl.
+ reflexivity.
+ simpl. reflexivity.
+ simpl. reflexivity.
- destruct T as [[h|]|[Tl Tr]]; intros HTm.
+ simpl. reflexivity.
+ simpl. reflexivity.
+ simpl. generalize (IH Tr). generalize (IH Tl). unfold octree_mtree.
destruct (mtree_octree Tl) as [Tlc|] eqn:Tle.
* { destruct (mtree_octree Tr) as [Trc|] eqn:Tre.
- intros IHl IHr. simpl. rewrite IHl.
+ rewrite IHr.
* reflexivity.
* revert HTm. apply mtree_normal_R.
+ revert HTm. apply mtree_normal_L.
- intros IHl IHr. simpl.
destruct (ctreeLinv Tlc) as [[alpha hl1]|] eqn:Tlce.
+ unfold mtreeB. rewrite <- IHl.
* { rewrite <- IHr.
- rewrite (ctreeLinv_singlebranch Tlc).
+ reflexivity.
+ assumption.
- revert HTm. apply mtree_normal_R.
}
* revert HTm. apply mtree_normal_L.
+ simpl. unfold mtreeB. rewrite <- IHl.
* { rewrite <- IHr.
- reflexivity.
- revert HTm. apply mtree_normal_R.
}
* revert HTm. apply mtree_normal_L.
}
* { destruct (mtree_octree Tr) as [Trc|] eqn:Tre.
- intros IHl IHr. simpl.
destruct (ctreeLinv Trc) as [[alpha hr1]|] eqn:Trce.
+ unfold mtreeB. rewrite <- IHl.
* { rewrite <- IHr.
- rewrite (ctreeLinv_singlebranch Trc).
+ reflexivity.
+ assumption.
- revert HTm. apply mtree_normal_R.
}
* revert HTm. apply mtree_normal_L.
+ simpl. unfold mtreeB. rewrite <- IHl.
* { rewrite <- IHr.
- reflexivity.
- revert HTm. apply mtree_normal_R.
}
* revert HTm. apply mtree_normal_L.
- intros IHl IHr. exfalso.
generalize HTm. rewrite <- IHl.
+ rewrite <- IHr.
* { simpl. intros [_ [_ [H1|H1]]].
- apply H1. apply mtree_hashroot_empty.
- apply H1. apply mtree_hashroot_empty.
}
* revert HTm. apply mtree_normal_R.
+ revert HTm. apply mtree_normal_L.
}
Qed.
Lemma ctree_mtree_hashroot_nonempty {n} :
forall T:ctree n,
mtree_hashroot (ctree_mtree T) <> None.
induction n as [|n IH].
- intros [h|[h hl]].
+ simpl. discriminate.
+ simpl. destruct (hlist_hashroot hl) as [k|]; discriminate.
- intros [[[[|] gamma] hl]|[h|[Tl|[Tr|[Tl Tr]]]]].
+ simpl. rewrite mtree_hashroot_empty. simpl.
destruct (mtree_hashroot (singlebranch_mtree hl gamma)) as [k|] eqn:H1.
* discriminate.
* exfalso. revert H1. apply mtree_hashroot_singlebranch_nonempty.
+ simpl. rewrite mtree_hashroot_empty. simpl.
destruct (mtree_hashroot (singlebranch_mtree hl gamma)) as [k|] eqn:H1.
* discriminate.
* exfalso. revert H1. apply mtree_hashroot_singlebranch_nonempty.
+ simpl. discriminate.
+ simpl.
destruct (mtree_hashroot (ctree_mtree Tl)) as [k|] eqn:H1.
* simpl. rewrite mtree_hashroot_empty. discriminate.
* exfalso. revert H1. apply IH.
+ simpl.
destruct (mtree_hashroot (ctree_mtree Tr)) as [k|] eqn:H1.
* simpl. rewrite mtree_hashroot_empty. discriminate.
* exfalso. revert H1. apply IH.
+ simpl.
destruct (mtree_hashroot (ctree_mtree Tl)) as [k|] eqn:H1.
* simpl. destruct (mtree_hashroot (ctree_mtree Tr)); discriminate.
* exfalso. revert H1. apply IH.
Qed.
Lemma octree_mtree_normal {n} (T:option (ctree n)) :
mtree_normal_p (octree_mtree T).
destruct T as [T|].
- induction n as [|n IH].
+ simpl. tauto.
+ simpl. destruct T as [[[[|] gamma] [h|[h hl]]]|[h|[Tl|[Tr|[Tl Tr]]]]].
* { unfold mtreeB. repeat split.
- apply empty_mtree_normal.
- apply singlebranch_mtree_normal.
- right. apply mtree_hashroot_singlebranch_nonempty.
}
* { unfold mtreeB. repeat split.
- apply empty_mtree_normal.
- apply singlebranch_mtree_normal.
- right. apply mtree_hashroot_singlebranch_nonempty.
}
* { unfold mtreeB. repeat split.
- simpl. apply singlebranch_mtree_normal.
- apply empty_mtree_normal.
- left. apply mtree_hashroot_singlebranch_nonempty.
}
* { unfold mtreeB. repeat split.
- simpl. apply singlebranch_mtree_normal.
- apply empty_mtree_normal.
- left. apply mtree_hashroot_singlebranch_nonempty.
}
* unfold mtreeH. tauto.
* { unfold mtreeB. repeat split.
- apply IH.
- apply empty_mtree_normal.
- left. apply ctree_mtree_hashroot_nonempty.
}
* { unfold mtreeB. repeat split.
- apply empty_mtree_normal.
- apply IH.
- right. apply ctree_mtree_hashroot_nonempty.
}
* { unfold mtreeB. repeat split.
- apply IH.
- apply IH.
- left. apply ctree_mtree_hashroot_nonempty.
}
- simpl. destruct n as [|n].
+ simpl. tauto.
+ simpl. tauto.
Qed.
Definition octree_approx_fun_p {n} (T:option (ctree n)) (f:bitseq n -> list asset) : Prop :=
mtree_approx_fun_p (octree_mtree T) f.
(*** This is used to deconstruct an octree at level n+1 into
either a hash (structure unknown) or two subtrees at level n.
The subtrees may be generated on the fly since we may need to modify them.
***)
Definition octree_S_inv {n} (T:option (ctree (S n))) :
sum hashval (prod (option (ctree n)) (option (ctree n))) :=
match T with
| Some (inl ((false,gamma), hl)) => inr (Some (ctreeL hl gamma),None)
| Some (inl ((true,gamma), hl)) => inr (None,Some (ctreeL hl gamma))
| Some (inr (inl h)) => inl h
| Some (inr (inr (inl Tl))) => inr (Some Tl, None)
| Some (inr (inr (inr (inl Tr)))) => inr (None, Some Tr)
| Some (inr (inr (inr (inr (Tl, Tr))))) => inr (Some Tl, Some Tr)
| None => inr (None,None)
end.
Definition onehlist_hlist (hl:option nehlist) : hlist :=
match hl with
| Some (inl h) => hlistH h
| Some (inr (a,hl)) => hlistC a hl
| None => hlistN
end.
Fixpoint tx_octree_trans_ {n:nat} : forall (inpl:list (bitseq n * hashval)%type) (outpl:list (bitseq n * asset)%type) (T:option (ctree n)), option (ctree n) :=
match n with
| O => fun inpl outpl =>
match inpl,outpl with
| nil,nil => fun (hl:option (ctree 0)) => hl
| _,_ => fun (hl:option (ctree 0)) =>
match hlist_new_assets (map (@snd (bitseq 0) asset) outpl) (remove_assets_hlist (onehlist_hlist hl) (map (@snd (bitseq 0) hashval) inpl)) with
| hlistN => None
| hlistH h' => Some(inl h')
| hlistC h' hl' => Some(inr (h',hl'))
end
end
| S n => fun inpl outpl =>
match inpl,outpl with
| nil,nil => fun (T:option (ctree (S n))) => T
| _,_ => (*** In this case since we're modifying subtrees, generate them on the fly and call recursively at level n ***)
fun (T:option (ctree (S n))) =>
match octree_S_inv T with
| inl h => T (*** structure unknown, error, but just return T ***)
| inr (Tl,Tr) =>
match tx_octree_trans_ (strip_bitseq_false inpl) (strip_bitseq_false outpl) Tl,tx_octree_trans_ (strip_bitseq_true inpl) (strip_bitseq_true outpl) Tr with
| None,None => None
| Some Tl',None => Some(inr (inr (inl Tl')))
| None,Some Tr' => Some(inr (inr (inr (inl Tr'))))
| Some Tl',Some Tr' => Some(inr (inr (inr (inr (Tl',Tr')))))
end
end
end
end.
Definition tx_octree_trans (tx:Tx) (T:option (ctree 160)) : option (ctree 160) :=
tx_octree_trans_ (tx_inputs tx) (add_vout (hashtx tx) (tx_outputs tx) 0) T.
Fixpoint ctree_supports_addr {n} : ctree n -> bitseq n -> Prop :=
match n with
| O => fun (T:ctree 0) (alpha:bitseq 0) => True
| S n => fun (T:ctree (S n)) (alpha:bitseq (S n)) =>
match T with
| inl (beta,hl) => True (*** To fail to support an address, there would need to be a summarizing hash between here and the address leaf. Since from here everything is either the leaf beta or an empty leaf, there are no such summarizing hashes. ***)
| inr (inl _) => False
| inr (inr (inl Tl)) =>
match alpha with
| (false,alphar) => ctree_supports_addr Tl alphar
| (true,alphar) => True (*** since empty ***)
end
| inr (inr (inr (inl Tr))) =>
match alpha with
| (false,alphar) => True (*** since empty ***)
| (true,alphar) => ctree_supports_addr Tr alphar
end
| inr (inr (inr (inr (Tl,Tr)))) =>
match alpha with
| (false,alphar) => ctree_supports_addr Tl alphar
| (true,alphar) => ctree_supports_addr Tr alphar
end
end
end.
Fixpoint ctree_supports_asset (a:asset) {n} : ctree n -> bitseq n -> Prop :=
match n with
| O => fun (hl:ctree 0) (alpha:bitseq 0) => In_hlist a (nehlist_hlist hl)
| S n => fun (T:ctree (S n)) (alpha:bitseq (S n)) =>
match T with
| inl (beta,hl) => if bitseq_eq_dec beta alpha then
In_hlist a (nehlist_hlist hl)
else
False
| inr (inl _) => False
| inr (inr (inl Tl)) =>
match alpha with
| (false,alphar) => ctree_supports_asset a Tl alphar
| (true,alphar) => False
end
| inr (inr (inr (inl Tr))) =>
match alpha with
| (false,alphar) => False
| (true,alphar) => ctree_supports_asset a Tr alphar
end
| inr (inr (inr (inr (Tl,Tr)))) =>
match alpha with
| (false,alphar) => ctree_supports_asset a Tl alphar
| (true,alphar) => ctree_supports_asset a Tr alphar
end
end
end.
Inductive ctree_asset_value_in T : list addr_assetid -> nat -> Prop :=
| ctree_asset_value_in_nil : ctree_asset_value_in T nil 0
| ctree_asset_value_in_cons h a u inpl alpha v :
ctree_asset_value_in T inpl v ->
ctree_supports_asset a T alpha ->
asset_value a = Some u ->
h = assetid a ->
ctree_asset_value_in T ((alpha,h)::inpl) (u+v)
| ctree_asset_value_in_skip h a inpl alpha v :
ctree_asset_value_in T inpl v ->
ctree_supports_asset a T alpha ->
asset_value a = None ->
h = assetid a ->
ctree_asset_value_in T ((alpha,h)::inpl) v
.
Lemma ctree_asset_value_in_app T inpl1 inpl2 utot1 utot2 :
ctree_asset_value_in T inpl1 utot1 ->
ctree_asset_value_in T inpl2 utot2 ->
ctree_asset_value_in T (inpl1 ++ inpl2) (utot1 + utot2).
intros H. induction H as [|h a u inpr1 alpha v H1 IH H2 H3 H4|h a inpr1 alpha v H1 IH H2 H3 H4].
- intros H1. exact H1.
- intros H5.
assert (L1: u + v + utot2 = u + (v + utot2)) by omega.
rewrite L1.
change (ctree_asset_value_in T ((alpha, h) :: (inpr1 ++ inpl2))
(u + (v + utot2))).
apply ctree_asset_value_in_cons with (a := a).
+ now apply IH.
+ assumption.
+ assumption.
+ assumption.
- intros H5.
change (ctree_asset_value_in T ((alpha, h) :: (inpr1 ++ inpl2))
(v + utot2)).
apply ctree_asset_value_in_skip with (a := a).
+ now apply IH.
+ assumption.
+ assumption.
+ assumption.
Qed.
(*** Precondition for checking if tx is a valid tx. ***)
Definition ctree_can_support_tx (tx:Tx) (T : ctree 160) : Prop :=
(forall alpha h, In (alpha,h) (tx_inputs tx) -> exists u, ctree_supports_asset (h,u) T alpha)
/\
(forall alpha u, In (alpha,u) (tx_outputs tx) -> ctree_supports_addr T alpha)
.
Definition ctree_supports_tx (tx:Tx) (T : ctree 160) fee rew : Prop :=
(forall alpha u, In (alpha,u) (tx_outputs tx) -> ctree_supports_addr T alpha)
/\
(exists utot:nat,
ctree_asset_value_in T (tx_inputs tx) utot
/\
asset_value_out (tx_outputs tx) + fee = utot + rew)
.
Definition octree_supports_tx (tx:Tx) (T : option (ctree 160)) fee rew : Prop :=
match T with
| None => False (*** We could say the empty tree supports an empty tx, but there seems to be no good reason for this. ***)
| Some T => ctree_supports_tx tx T fee rew
end.
Lemma ctree_supports_asset_S_inv_L (a:asset) {n} :
forall T:ctree (S n),
forall Tl:ctree n, forall Tr:option (ctree n),
forall alpha,
octree_S_inv (Some T) = inr (Some Tl, Tr) ->
ctree_supports_asset a T (false, alpha) ->
ctree_supports_asset a Tl alpha.
intros [[[[|] alpha] h]|[h|[Tl'|[Tr'|[Tl' Tr']]]]]; try (simpl; discriminate).
- intros Tl [Tr|] beta H1 H2; simpl in H1.
+ inversion H1.
+ inversion H1. unfold ctree_supports_asset in H2.
change (if @bitseq_eq_dec (S n) (false,alpha) (false,beta) then In_hlist a (nehlist_hlist h) else False)
in H2.
destruct (@bitseq_eq_dec (S n) (false,alpha) (false,beta)) as [D1|D1].
* { destruct n as [|n].
- simpl. tauto.
- change (if bitseq_eq_dec alpha beta then In_hlist a (nehlist_hlist h) else False).
destruct (bitseq_eq_dec alpha beta) as [D2|D2].
+ tauto.
+ inversion D1. contradiction.
}
* contradiction H2.
- intros Tl [Tr|] beta H1 H2; simpl in H1.
+ inversion H1.
+ inversion H1. simpl in H2. congruence.
- intros Tl [Tr|] beta H1 H2; simpl in H1.
+ inversion H1. simpl in H2. congruence.
+ inversion H1.
Qed.
Lemma ctree_supports_asset_S_inv_R (a:asset) {n} :
forall T:ctree (S n),
forall Tl:option (ctree n), forall Tr:ctree n,
forall alpha,
octree_S_inv (Some T) = inr (Tl, Some Tr) ->
ctree_supports_asset a T (true, alpha) ->
ctree_supports_asset a Tr alpha.
intros [[[[|] alpha] h]|[h|[Tl'|[Tr'|[Tl' Tr']]]]]; try (simpl; discriminate).
- intros [Tl|] Tr beta H1 H2; simpl in H1.
+ inversion H1.
+ inversion H1. unfold ctree_supports_asset in H2.
change (if @bitseq_eq_dec (S n) (true,alpha) (true,beta) then In_hlist a (nehlist_hlist h) else False)
in H2.
destruct (@bitseq_eq_dec (S n) (true,alpha) (true,beta)) as [D1|D1].
* { destruct n as [|n].
- simpl. tauto.
- change (if bitseq_eq_dec alpha beta then In_hlist a (nehlist_hlist h) else False).
destruct (bitseq_eq_dec alpha beta) as [D2|D2].
+ tauto.
+ inversion D1. contradiction.
}
* contradiction H2.
- intros [Tl|] Tr beta H1 H2; simpl in H1.
+ inversion H1.
+ inversion H1. simpl in H2. congruence.
- intros [Tl|] Tr beta H1 H2; simpl in H1.
+ inversion H1. simpl in H2. congruence.
+ inversion H1.
Qed.
Definition ctree_valid (T:ctree 160) : Prop := mtree_valid (ctree_mtree T).
Opaque ctree_supports_asset.
Theorem ctree_supports_tx_can_support tx (T:ctree 160) fee rew :
ctree_supports_tx tx T fee rew ->
ctree_can_support_tx tx T.
intros [Hs1 [utot [Hs2 Hs3]]]. repeat split.
- destruct tx as [inpl outpl].
clear Hs1 rew Hs3.
change (ctree_asset_value_in T inpl utot) in Hs2.
change (forall (alpha : addr) (h : hashval),
In (alpha, h) inpl ->
exists oblu, ctree_supports_asset (h, oblu) T alpha).
induction Hs2 as [|h a u inpl alpha v H1 IH H2 H3 H4|h a inpl alpha v H1 IH H2 H3 H4].
+ intros alpha h [].
+ intros beta k [H5|H5].
* inversion H5. subst beta. subst k. subst h. exists (assetobl a,assetpre a).
destruct a as [h [obl w]]. exact H2.
* apply IH. exact H5.
+ intros beta k [H5|H5].
* inversion H5. subst beta. subst k. subst h. exists (assetobl a,assetpre a).
destruct a as [h [obl w]]; exact H2.
* apply IH. exact H5.
- exact Hs1.
Qed.
Lemma empty_mtree_trans {n:nat} :
empty_mtree n = tx_mtree_trans_ nil nil (empty_mtree n).
destruct n as [|n].
- simpl. reflexivity.
- simpl. reflexivity.
Qed.
Lemma tx_octree_trans_outpl_nonempty {n} (gamma:bitseq n) (v:asset) outpl :
tx_octree_trans_ nil ((gamma,v)::outpl) None <> None.
induction n as [|n IH].
- simpl. discriminate.
- destruct gamma as [[|] gamma].
+ simpl. destruct (tx_octree_trans_ nil (strip_bitseq_false outpl) None) as [Tl'|].
* { (*** Coq needs some serious help via change here, or the next destruct has no effect. ***)
change ((fun x : option (ctree n) =>
match x return option (ctree (S n)) with
| Some Tr'0 => Some (inr (inr (inr (inr (Tl', Tr'0)))))
| None => Some (inr (inr (inl Tl')))
end <> None)
(tx_octree_trans_ nil ((gamma, v) :: strip_bitseq_true outpl) None)).
destruct (tx_octree_trans_ nil ((gamma, v) :: strip_bitseq_true outpl) None) as [Tr'|].
- discriminate.
- discriminate.
}
* { (*** Again, Coq needs this change before the destruct to work properly. ***)
change ((fun x : option (ctree n) =>
match x return option (ctree (S n)) with
| Some Tr' => Some (inr (inr (inr (inl Tr'))))
| None => None
end <> None)
(tx_octree_trans_ nil ((gamma, v) :: strip_bitseq_true outpl) None)).
destruct (tx_octree_trans_ nil ((gamma, v) :: strip_bitseq_true outpl) None) as [Tr'|] eqn: H1.
- discriminate.
- exfalso. revert H1. apply IH.
}
+ simpl. (*** In this case, Coq needs the change before this destruct. ***)
change ((fun x : option (ctree n) =>
match x return option (ctree (S n)) with
| Some Tl' =>
match tx_octree_trans_ nil (strip_bitseq_true outpl) None with
| Some Tr' => Some (inr (inr (inr (inr (Tl', Tr')))))
| None => Some (inr (inr (inl Tl')))
end
| None =>
match tx_octree_trans_ nil (strip_bitseq_true outpl) None with
| Some Tr' => Some (inr (inr (inr (inl Tr'))))
| None => None
end
end <> None)
(tx_octree_trans_ nil ((gamma, v) :: strip_bitseq_false outpl) None)).
destruct (tx_octree_trans_ nil ((gamma,v) ::(strip_bitseq_false outpl)) None) as [Tl'|] eqn: H1.
* { destruct (tx_octree_trans_ nil (strip_bitseq_true outpl) None) as [Tr'|].
- discriminate.
- discriminate.
}
* { destruct (tx_octree_trans_ nil (strip_bitseq_true outpl) None) as [Tr'|].
- discriminate.
- exfalso. revert H1. apply IH.
}
Qed.
Lemma tx_trans_mtree_emptyctree_eq {n:nat} :
forall outpl,
octree_mtree
(tx_octree_trans_ nil outpl None) =
tx_mtree_trans_ nil outpl (empty_mtree n).
induction n as [|n IH].
- intros [|[k v] outpr].
+ simpl. reflexivity.
+ simpl. reflexivity.
- intros [|[gamma v] outpr].
+ simpl. reflexivity.
+ set (outpl := ((gamma, v) :: outpr)).
change (@octree_mtree (S n) (match tx_octree_trans_ nil (strip_bitseq_false outpl) None,tx_octree_trans_ nil (strip_bitseq_true outpl) None with
| None,None => None
| Some Tl',None => Some(inr (inr (inl Tl')))
| None,Some Tr' => Some(inr (inr (inr (inl Tr'))))
| Some Tl',Some Tr' => Some(inr (inr (inr (inr (Tl',Tr')))))
end) =
mtreeB (tx_mtree_trans_ nil (strip_bitseq_false outpl) (empty_mtree n))
(tx_mtree_trans_ nil (strip_bitseq_true outpl) (empty_mtree n))).
generalize (IH (strip_bitseq_false outpl)).
generalize (IH (strip_bitseq_true outpl)).
destruct (tx_octree_trans_ nil (strip_bitseq_false outpl) None) as [Tl'|] eqn: ETl'.
* { destruct (tx_octree_trans_ nil (strip_bitseq_true outpl) None) as [Tr'|] eqn: ETr'.
- intros H1 H2.
change (mtreeB (ctree_mtree Tl') (ctree_mtree Tr') =
mtreeB (tx_mtree_trans_ nil (strip_bitseq_false outpl) (empty_mtree n))
(tx_mtree_trans_ nil (strip_bitseq_true outpl) (empty_mtree n))).
f_equal.
+ exact H2.
+ exact H1.
- intros H1 H2.
change (mtreeB (ctree_mtree Tl') (empty_mtree n) =
mtreeB (tx_mtree_trans_ nil (strip_bitseq_false outpl) (empty_mtree n))
(tx_mtree_trans_ nil (strip_bitseq_true outpl) (empty_mtree n))).
f_equal.
+ exact H2.
+ exact H1.
}
* { destruct (tx_octree_trans_ nil (strip_bitseq_true outpl) None) as [Tr'|] eqn: ETr'.
- intros H1 H2.
change (mtreeB (empty_mtree n) (ctree_mtree Tr') =
mtreeB (tx_mtree_trans_ nil (strip_bitseq_false outpl) (empty_mtree n))
(tx_mtree_trans_ nil (strip_bitseq_true outpl) (empty_mtree n))).
f_equal.
+ exact H2.
+ exact H1.
- intros H1 H2. exfalso. (*** This case is impossible since outpl is nonempty and so it must have been put into either the left or right. ***)
destruct gamma as [[|] gamma].
+ unfold outpl in ETr'. revert ETr'. apply tx_octree_trans_outpl_nonempty.
+ unfold outpl in ETl'. revert ETl'. apply tx_octree_trans_outpl_nonempty.
}
Qed.
Lemma tx_octree_trans_S_inv_lemNN {n} :
forall inpl outpl,
forall T:option (ctree (S n)),
forall Tl Tr:option (ctree n),
inpl <> nil \/ outpl <> nil ->
octree_S_inv T = inr (Tl, Tr) ->
tx_octree_trans_ (strip_bitseq_false inpl) (strip_bitseq_false outpl) Tl = None ->
tx_octree_trans_ (strip_bitseq_true inpl) (strip_bitseq_true outpl) Tr = None ->
tx_octree_trans_ inpl outpl T = None.
intros [|a inpl] [|b outpl] T Tl Tr H1 H2 H3 H4.
- exfalso. tauto.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false nil) (strip_bitseq_false (b :: outpl)) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true nil) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true nil) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= None).
rewrite H3. rewrite H4.
reflexivity.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false (a::inpl)) (strip_bitseq_false nil) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true nil) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true nil) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= None).
rewrite H3. rewrite H4.
reflexivity.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false (a::inpl)) (strip_bitseq_false (b :: outpl)) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= None).
rewrite H3. rewrite H4.
reflexivity.
Qed.
Lemma tx_octree_trans_S_inv_lemSN {n} :
forall inpl outpl,
forall T:option (ctree (S n)),
forall Tl Tr:option (ctree n), forall Tl':ctree n,
inpl <> nil \/ outpl <> nil ->
octree_S_inv T = inr (Tl, Tr) ->
tx_octree_trans_ (strip_bitseq_false inpl) (strip_bitseq_false outpl) Tl = Some Tl' ->
tx_octree_trans_ (strip_bitseq_true inpl) (strip_bitseq_true outpl) Tr = None ->
tx_octree_trans_ inpl outpl T = Some(ctreeBL Tl').
intros [|a inpl] [|b outpl] T Tl Tr Tl' H1 H2 H3 H4.
- exfalso. tauto.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false nil) (strip_bitseq_false (b :: outpl)) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true nil) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true nil) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= Some (ctreeBL Tl')).
rewrite H3. rewrite H4.
reflexivity.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false (a::inpl)) (strip_bitseq_false nil) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true nil) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true nil) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= Some (ctreeBL Tl')).
rewrite H3. rewrite H4.
reflexivity.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false (a::inpl)) (strip_bitseq_false (b :: outpl)) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= Some (ctreeBL Tl')).
rewrite H3. rewrite H4.
reflexivity.
Qed.
Lemma tx_octree_trans_S_inv_lemNS {n} :
forall inpl outpl,
forall T:option (ctree (S n)),
forall Tl Tr:option (ctree n), forall Tr': ctree n,
inpl <> nil \/ outpl <> nil ->
octree_S_inv T = inr (Tl, Tr) ->
tx_octree_trans_ (strip_bitseq_false inpl) (strip_bitseq_false outpl) Tl = None ->
tx_octree_trans_ (strip_bitseq_true inpl) (strip_bitseq_true outpl) Tr = Some Tr' ->
tx_octree_trans_ inpl outpl T = Some (ctreeBR Tr').
intros [|a inpl] [|b outpl] T Tl Tr Tr' H1 H2 H3 H4.
- exfalso. tauto.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false nil) (strip_bitseq_false (b :: outpl)) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true nil) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true nil) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= Some (ctreeBR Tr')).
rewrite H3. rewrite H4.
reflexivity.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false (a::inpl)) (strip_bitseq_false nil) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true nil) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true nil) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= Some (ctreeBR Tr')).
rewrite H3. rewrite H4.
reflexivity.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false (a::inpl)) (strip_bitseq_false (b :: outpl)) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= Some (ctreeBR Tr')).
rewrite H3. rewrite H4.
reflexivity.
Qed.
Lemma tx_octree_trans_S_inv_lemSS {n} :
forall inpl outpl,
forall T:option (ctree (S n)),
forall Tl Tr:option (ctree n), forall Tl' Tr':ctree n,
inpl <> nil \/ outpl <> nil ->
octree_S_inv T = inr (Tl, Tr) ->
tx_octree_trans_ (strip_bitseq_false inpl) (strip_bitseq_false outpl) Tl = Some Tl' ->
tx_octree_trans_ (strip_bitseq_true inpl) (strip_bitseq_true outpl) Tr = Some Tr' ->
tx_octree_trans_ inpl outpl T = Some(ctreeB Tl' Tr').
intros [|a inpl] [|b outpl] T Tl Tr Tl' Tr' H1 H2 H3 H4.
- exfalso. tauto.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false nil) (strip_bitseq_false (b :: outpl)) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true nil) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true nil) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= Some (ctreeB Tl' Tr')).
rewrite H3. rewrite H4.
reflexivity.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false (a::inpl)) (strip_bitseq_false nil) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true nil) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true nil) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= Some (ctreeB Tl' Tr')).
rewrite H3. rewrite H4.
reflexivity.
- simpl. rewrite H2.
change (match
tx_octree_trans_ (strip_bitseq_false (a::inpl)) (strip_bitseq_false (b :: outpl)) Tl
with
| Some Tl' =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeB Tl' Tr')
| None => Some (ctreeBL Tl')
end
| None =>
match tx_octree_trans_ (strip_bitseq_true (a::inpl)) (strip_bitseq_true (b :: outpl)) Tr
with
| Some Tr' => Some (ctreeBR Tr')
| None => None
end
end
= Some (ctreeB Tl' Tr')).
rewrite H3. rewrite H4.
reflexivity.
Qed.
Lemma tx_octree_trans_nochange_lem {n} :
forall T:option (ctree n),
tx_octree_trans_ nil nil T = T.
destruct n as [|n].
- intros T. simpl. reflexivity.
- intros T. simpl. reflexivity.
Qed.
Lemma octree_mtree_S_inv_SS {n} :
forall T:option (ctree (S n)),
forall Tl Tr:ctree n,
octree_S_inv T = inr (Some(Tl), Some(Tr)) ->
octree_mtree T = mtreeB (octree_mtree (Some Tl)) (octree_mtree (Some Tr)).
intros [[[[[|] alpha] h]|[h|[Tl'|[Tr'|[Tl' Tr']]]]]|] Tl Tr; try (simpl; discriminate).
simpl. intros H1. inversion H1. reflexivity.
Qed.
Lemma octree_mtree_S_inv_SN {n} :
forall T:option (ctree (S n)),