rocq/theories/Streams.v
Selected stream queries and close, over explicit projections of the application's libc world. stream_protocol is a projection, not a second stdout queue: the composite world must use its authoritative shutdown stdout. Physical buffering and ownership are separate. These are trusted libc contracts, not a native adequacy proof.
An open stream's identifier, logical protocol and physical buffered count. In wide mode the count is in wide characters, not bytes.
| stream_identifier | : Z | |
| stream_protocol | ||
| stream_pending | : Z |
The integration obligations for a selected native stream. stream_rep includes native FILE validity, lock/TLS sources, orientation, physical buffering, and exclusive close ownership. Releases name only owned heap objects, never caller-owned setvbuf storage or static FILEs. stream_frame preserves unrelated state, including the shutdown callback inventory, but may change errno. Effects separately frame caller memory. stream_state_at survives handle consumption and MUST project the same authoritative shutdown stdout, not store a copy. Wide realization must cover physical buffering and shared conversion cache mutations; a reference-count decrement is not an owned free. No projection grants authority merely by its address.
| stream_at | : world → ptr → optionstream_info | |
| stream_state_at | : world → ptr → stream_state | |
| stream_rep | : mem → world → Prop | |
| stream_sources | ||
| stream_writes | ||
| stream_aux_roots | ||
| stream_releases | : world → ptr → listZ | |
| stream_requests | : world → ptr → Z → Z → Prop | |
| stream_frame | : ptr → world → world → Prop | |
| stream_wide_settlement | : world → ptr → stream_state → stream_state → bool → Prop |
Scalar-only roots (notably errno) need not authorize aux mutation. Test entry memory, not historical born objects after a release. The ordinary effects path still bounds all writes independently.
Canonical physical size_t and a well-formed logical protocol. A physical count is deliberately not equated with outstanding output.
A selected handle is open, represented and has writable stream roots. The stronger native representation is an independent premise.
Canonical signed int results are carried as unsigned W bits.
EOF at this glibc pin, not a mathematical negative machine word.
One pointer argument and a discarded or correctly classed result.
Readable caller arguments cannot delegate new persistent writable roots: only the old stream roots and fresh allocations may do so. Future private sources retain old source capabilities or born ones; future release rights retain old ownership or fresh allocation. A writable root alone is not evidence of exclusive release ownership.
Admission to queries and close is independent of the chosen result.
ferror observes the error flag without changing the stream. Its nonzero return is not specified as one. Locks may still mutate.
__fpending returns the physical count, preserving stream state.
Query prefixes preserve the selected open stream and have no output. Queries may lock private FILE storage, but preserve caller bytes and scalar errno. This is a trusted entry-memory frame, not a consequence of the larger ordinary write footprint. Queries do not allocate, hence have no modeled resource ending.
ferror's exact P-to-W contract.
__fpending's exact P-to-L contract; its C symbol has two underscores.
An owned release has consumed a heap object's lifetime, including on EOF. The capability remains an identity, but is no longer live.
Byte settlement uses the existing FIFO without new acceptance. Wide settlement instead requires independent selected native coverage of conversion and physical buffering, including completion when complete is true. It uses the same orientation/error projection; there is no wide queue hidden in the byte protocol.
Completed settlement empties the authoritative protocol; wide physical settlement additionally needs the supplied realization.
Explore proof 8 tactics
Initial goal
intros world model w p old final H
unfold stream_settlement in H
destruct orientationold
3 openfocused goal
focused goal
–destruct H as actions & _ & _ & Hdone
3 opendeferred goal
deferred goal
auto
2 opendeferred goal
deferred goal
–destruct H as actions & _ & _ & Hdone
2 opendeferred goal
auto
deferred goal
–tauto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A close prefix may settle old output but never accept new output. A resource stop need not have closed the stream or released storage. Wide-stream settlement remains an explicit integration obligation.
Close settles all old obligations in FIFO order (delivery OR error discard), consumes the handle and owned heaps on both result paths. A descriptor close failure can return EOF after all output delivered.
P-to-W close with separate ownership and request footprints.
Consequences of trusted calls over any runtime, without changing the supplied machine or adding runtime axioms.
Construct a normal query from independently established effects and postconditions. Prefix and native representation are not inferred.
Explore proof 12 tactics
Initial goal
intros world model r args xs s m w born trace result s′ m′ w′ Habi Hpre Hprefix Hpost
eapply E.invoke_normal with born := born ; try exact Habi ; try exact Hpre ; try exact Hprefix ; try exact Hpost ; try discriminate
intros values Heq
injection Heq as ←
split ; | constructor ; exact I | constructor
exists WIntresult
split ; reflexivity |
simpl
destruct Hpost as p & info & n & _ & _ & _ & _ & _ & _ & Hend & Hrange & _
injection Hend as ←
rewrite Z.mod_small by exact Hrange
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
ferror cannot take the resource rule: its request set is empty.
Explore proof 4 tactics
Initial goal
intros world model r args xs s m w trace ending s′ m′ w′ Hcall
inversion Hcall ; subst
2 openfocused goal
–match goal withHpost : contract_post_ _ _ _ _ _ _ _ |- _⇒exists born ; exact Hpostend
deferred goal
–contradiction
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
__fpending likewise has only ordinary query completions.
Explore proof 4 tactics
Initial goal
intros world model r args xs s m w trace ending s′ m′ w′ Hcall
inversion Hcall ; subst
2 openfocused goal
–match goal withHpost : contract_post_ _ _ _ _ _ _ _ |- _⇒exists born ; exact Hpostend
deferred goal
–contradiction
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A resource-ending close has no ordinary-return postcondition.
Explore proof 6 tactics
Initial goal
intros world model r args xs s m w trace ending s′ m′ w′ Hcall
inversion Hcall ; subst
2 openfocused goal
–left
2 opendeferred goal
match goal withHpost : contract_post_ _ _ _ _ _ _ _ |- _⇒exists born ; exact Hpostend
deferred goal
–right
eauto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A returning close consumes its handle and owned heap storage and settles the surviving authoritative protocol, on both 0 and EOF.
Explore proof 7 tactics
Initial goal
intros world model r args p s m w trace result s′ m′ w′ Hcall
destruct fclose_invocation_ _ _ _ _ _ _ _ _ _ _ _ _ Hcall as born & q & info & final & n & Hargs & _ & Hsettle & Hfinal & Hresult & Hclosed & Hfree & _ & _ & _ & Hend | why & Hbad & _ ; | discriminate Hbad
injection Hargs as ←
injection Hend as ←
rewrite Hfinal
repeat split ; try assumption
eapply stream_settlement_complete ; exact Hsettle
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Standalone compatibility wrapper; logic clients supply their own machine to StreamsOn so its invocation type is exactly theirs.
Physical buffering and protocol outstanding bytes are independent.
Explore proof 3 tactics
Initial goal
unfold stream_info_wf , stream_wf
simpl
split ; split ; repeat constructor ; lia | auto | lia
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A canonical non-one error result is admitted by the result relation.
Explore proof 1 tactics
Initial goal
split ; lia | split ; discriminate
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.