proofs/nat_interval.bend
1import Base
2import stelliferous@0.0.3.0/proofs/nat_order.bend as Order
3import stelliferous@0.0.3.0/proofs/nat_to_u32_bounds.bend as Bounds
4import stelliferous@0.0.3.0/proofs/natural_addition.bend as Addition
5
6def shifted_inside(+begin: Nat,+end: Nat,+query: Nat,+lower: {Nat.is_le(begin,query) == True{} : Bool},+upper: {Nat.is_lt(query,end) == True{} : Bool}) ->
7 {Nat.is_lt(Nat.sub(query,begin),Nat.sub(end,begin)) == True{} : Bool}:
8 +ordered = Bounds.strict_le(begin,end,Order.le_lt_trans(begin,query,end,lower,upper))
9 Order.cancel_offset_lt(begin,Nat.sub(query,begin),Nat.sub(end,begin),
10 %Equal.sym(Nat,Nat.add(begin,Nat.sub(query,begin)),query,Order.restore_shift(begin,query,lower)) : {Nat.is_lt(_,Nat.add(begin,Nat.sub(end,begin))) == True{} : Bool}
11 %Equal.sym(Nat,Nat.add(begin,Nat.sub(end,begin)),end,Order.restore_shift(begin,end,ordered)) : {Nat.is_lt(query,_) == True{} : Bool} upper)
12
13def shifted_span(+first: Nat,+rows: Nat,+begin: Nat,+end: Nat,lower: {Nat.is_le(first,begin) == True{} : Bool},
14 ordered: {Nat.is_le(begin,end) == True{} : Bool},upper: {Nat.is_le(end,Nat.add(first,rows)) == True{} : Bool}) ->
15 {Nat.is_le(Nat.add(Nat.sub(begin,first),Nat.sub(end,begin)),rows) == True{} : Bool}:
16 Order.cancel_offset_le(first,Nat.add(Nat.sub(begin,first),Nat.sub(end,begin)),rows,
17 %Addition.associative(first,Nat.sub(begin,first),Nat.sub(end,begin)) : {Nat.is_le(_,Nat.add(first,rows)) == True{} : Bool}
18 %Equal.sym(Nat,Nat.add(first,Nat.sub(begin,first)),begin,Order.restore_shift(first,begin,lower)) : {Nat.is_le(Nat.add(_,Nat.sub(end,begin)),Nat.add(first,rows)) == True{} : Bool}
19 %Equal.sym(Nat,Nat.add(begin,Nat.sub(end,begin)),end,Order.restore_shift(begin,end,ordered)) : {Nat.is_le(_,Nat.add(first,rows)) == True{} : Bool} upper)
20
21# A query lies strictly before or at/after the end of a half-open interval.
22type Outside<-start: Nat,-length: Nat,-query: Nat> is Data:
23 Before{bound: {Nat.is_lt(query,start) == True{} : Bool}}
24 After{bound: {Nat.is_le(Nat.add(start,length),query) == True{} : Bool}}
25
26def outside_head(+start: Nat,+remaining: Nat,+query: Nat,outside: Outside<start,1n+remaining,query>) ->
27 {Nat.is_eq(query,start) == False{} : Bool}:
28 match outside:
29 case Before{bound}: Order.less_not_equal(query,start,bound)
30 case After{bound}:
31 %Equal.sym(Bool,Nat.is_eq(query,start),Nat.is_eq(start,query),Order.equal_symmetric(query,start)) : {_ == False{} : Bool}
32 Order.less_not_equal(start,query,Order.room_index(start,remaining,query,bound))
33
34def outside_tail(+start: Nat,+remaining: Nat,+query: Nat,outside: Outside<start,1n+remaining,query>) -> Outside<1n+start,remaining,query>:
35 match outside:
36 case Before{bound}: Before{Order.lt_succ(query,start,Bounds.strict_le(query,start,bound))}
37 case After{bound}: After{Order.advance_room(start,remaining,query,bound)}