rocq/theories/LocaleLogic.v
The locale world in the program logic of Logic.v (docs/logic.md, "Strings the world lends"): locale_wi, the world interpretation of a program that calls setlocale, over Campaign 4's locale_world (Locale.v), and what it gives the triples of LentLogic.v and HelloLocale.v.
locale_wi rep m w h asks of the memory m and the ghost heap h:
locale_ready: setlocale's trusted representation rep, its writable roots, every category's name a readable C string, its read spans, the heap objects it owns, the names' aligned bases;roots_apartandids_apart: the roots setlocale writes and the objects it may release are apart from the program's pieces, as the frame of an external call needs (prefix_agrees);cap_private: the object of every read, root and name capability owns no piece of h, so libc's locale memory is not the program's;names_current: every ghost name piece is a category's current name with its text, so alenttoken is the world's name;codec_current: the codec piece, under the keycodec_key, holds the world's current codec, so a conversion can name the codec a setter selected.
From it, locale_wi_lent is LentLogic.v's hypothesis lent_at for every ghost name, and locale_wi_pre and locale_wi_query are HelloLocale.v's premises on setlocale's query, the latter from Campaign 4's LocaleOn instance over the logic's own machine. A safepoint keeps it where it keeps rep and readiness (locale_wi_safepoint).
A setter keeps it too, with every category renamed to its new name (locale_wi_setter): the frame keeps libc's roots apart, and Campaign 4's private provenance (locale_delegates_private) makes every new read, root and name a born object or an old private one. The setter also gives the codec piece the new codec. locale_set_return is that for setlocale(c, p), in the form of wp_lend's premise, and wp_setlocale_set is the setter's triple.
The world interpretation
The capability c names an object, read-write or read-only, that owns no piece of memory of h; a null or function capability names none.
Every ghost name piece of h is the current name, with its text, of a category of the world w.
The key of the codec piece, which is no category's.
The codec piece of h, if any, holds the codec of the world w.
The world interpretation of a program that calls setlocale, whose trusted representation is rep: in the memory m and against the ghost heap h, the world w is ready, libc's roots and releasable objects are apart from the program's pieces, its read, root and name capabilities are private, and the ghost names and the codec are current.
Lent names
An access that succeeds through a read-write or read-only capability of b, from a for n bytes, lies in b's region.
Explore proof 6 tactics
Initial goal
intros Hc Ha
unfold access_res , cap_access_res in Ha
destruct Hc as → | → ; destruct object_regionb m_regionsm as reg | eqn: E ; try discriminate Ha
2 openfocused goal
all: destruct b ≤? a && a + n ≤? r_endreg eqn: Hb ; | discriminate Ha
2 openfocused goal
all: apply andb_true_iff in Hb as H1 H2 ; apply Z.leb_le in H1 ; apply Z.leb_le in H2
2 openfocused goal
all: exists reg ; auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Under locale_wi, in a memory whose live objects are apart, whose objects fit and whose freed objects are empty, every ghost name is lent where lent_at says: the category's name is a C string in a live object at a multiple of 8, which, being private, is none of the program's, so no live object owning a piece overlaps it.
Explore proof 18 tactics
Initial goal
intros Hready & _ & _ & _ & Hpriv & Hcur & _ Hd Hfit Hfree Hk
destruct Hcur_ _ _ Hk as Hcat & → & →
pose proof Hready as _ & _ & Hstr & _ & _ & Hal
destruct Hstrk Hcat as Hnz Hcs
destruct Halk Hcat as b & Hc & Hb8
destruct access_region_ _ _ _ _ _ _ Hc proj1Hcs as reg & E & Hlo & Hhi
destruct Hfitb reg E as Hb0 H48
assert L : r_lifereg = Live
2 openfocused goal
{destruct r_lifereg eqn: L ; reflexivity |
2 opendeferred goal
pose proof Hfreeb reg E L
2 opendeferred goal
lia
deferred goal
split ; exact Hcs |
split ; lia |
split ; lia |
split ; exists b ; auto |
intros a Ha l & v & reg′ & Hl & Hm & Hlv & Hin
assert Hne : piece_idl ≠ b by exact Hprivk Hcat b Hc b l v or_introleq_refl Hl Hm
destruct Hd_ _ _ _ Hlv conjE L Hne ; lia
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Renaming the ghost names
Renaming keeps every piece of memory.
Explore proof 6 tactics
Initial goal
intros Hm
induction ks as | k ks IH ; reflexivity |
cbn [ rename ]
rewrite lookup_insert_ne ; exact IH |
intros ←
exact Hm
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A key renaming does not touch keeps its name.
Explore proof 9 tactics
Initial goal
intros Hk
induction ks as | k′ ks IH ; reflexivity |
cbn [ rename ]
rewrite lookup_insert_ne ; | intros E ; injection E as → ; apply Hk ; left ; reflexivity
apply IH
intros Hin
apply Hk
right
exact Hin
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An address a renamed heap owns, the heap owned.
Explore proof 4 tactics
Initial goal
intros l & v & reg & Hl & Hm & Hlv & Hin
exists l, v, reg
rewrite rename_mem_ _ _ _ Hm in Hl
auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Objects apart from h are apart from it renamed.
Explore proof 3 tactics
Initial goal
intros Ha b l v Hb Hl Hm
rewrite rename_mem_ _ _ _ Hm in Hl
exact Hab l v Hb Hl Hm
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A capability private to h is private to it renamed.
Explore proof 3 tactics
Initial goal
intros Hc b Hb
apply ids_apart_rename
exact Hcb Hb
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
What the setter's locale_retained_cap keeps private: a born object, apart from h, or an old private source's own capability.
Explore proof 13 tactics
Initial goal
intros _ & _ & _ & Hsrc & Hnames & _ Hb base & Hin & Hc | s & Hin & →
2 openfocused goal
–intros b Hc′
2 opendeferred goal
assert b = base as →
3 openfocused goal
deferred goal
{destruct Hc as → | → ; destruct Hc′ as E | E ; congruence
2 opendeferred goal
deferred goal
intros b′ l v Hb′ Hl Hm
2 opendeferred goal
destruct Hb′ as ← |
2 opendeferred goal
exact Hbbase l v Hin Hl Hm
deferred goal
–unfold locale_private_sources in Hin
apply in_app_or in Hin as Hin | Hin
2 openfocused goal
+rewrite List.Forall_forall in Hsrc
2 opendeferred goal
exact Hsrcs Hin
deferred goal
+apply in_map_iff in Hin as k & ← & Hk
exact Hnamesk Hk
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The new names, after a setter, of every category of the world w'.
The codec piece holding the codec c.
The ghost heap h with every category renamed to its name in w' and the codec piece holding w''s codec: what a setter makes of it.
Relocaling keeps every piece of memory.
Explore proof 7 tactics
Initial goal
intros Hm
unfold relocale
rewrite overwrite_out ; exact rename_mem_ _ _ _ Hm |
cbn
rewrite list_elem_of_singleton
intros →
exact Hm
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An address a relocaled heap owns, the heap owned.
Explore proof 4 tactics
Initial goal
intros l & v & reg & Hl & Hm & Hlv & Hin
exists l, v, reg
rewrite relocale_mem_ _ _ Hm in Hl
auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A capability private to h is private to it relocaled.
Explore proof 3 tactics
Initial goal
intros Hc b Hb b′ l v Hb′ Hl Hm
rewrite relocale_mem_ _ _ Hm in Hl
exact Hcb Hb b′ l v Hb′ Hl Hm
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
After a setter with private provenance, from the world w against the ghost heap h, to the world w' in m': if w' is ready, the frame kept h agreeing and libc's old roots apart, and the born objects are none of h's, then locale_wi holds of w' and h with every category renamed to its new name and the codec piece holding the new codec (relocale).
Proof 51 steps Qed
The locale logic over any runtime R.
setlocale's query of a category whose name is lent is admitted: the world is ready and the category is one of its own.
Explore proof 5 tactics
Initial goal
intros Hready & _ & _ & _ & _ & Hcur & _ Hk Hz
destruct Hcur_ _ _ Hk as Hcat & _ & _
split ; exact Hready |
exists k, z
auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
setlocale's query of a category whose name is lent returns that name and changes nothing.
Explore proof 4 tactics
Initial goal
intros _ & _ & _ & _ & _ & Hcur & _ Hk Hz Hi
destruct Hcur_ _ _ Hk as _ & → & _
destruct LC.setlocale_query_invocation_ _ _ _ _ _ _ _ _ _ _ _ _ _ Hz Hi as _ & → & → & → & →
auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
setlocale's setter of the category c, with a string argument p, keeps the frame of a program under locale_wi: every invocation that returns, from a state interpreted with the ghost heap h, returns null or c's new name, keeps h agreeing, the live objects apart and the runtime ready, and locale_wi holds of h with every category renamed to its new name (locale_wi_setter). This is wp_lend's premise for setlocale(c, p), with the new names current_names of the world after the call.
Proof 41 steps Qed
A safepoint keeps locale_wi where it keeps rep and readiness: the roots stay apart since no region changes (collector_live), and the rest is of the world and the ghost heap.
Explore proof 13 tactics
Initial goal
intros Hst
split
intros s m s′ m′ w h Hsp Hr & Ha & Hrest
split ; exact Hst_ _ _ _ _ Hsp Hr |
split ; | exact Hrest
intros sp a Hin Hs l & v & reg & Hl & Hm & E Hlive & Hb
apply Hasp a Hin Hs
rewrite R.collector_live_ _ _ _ Hsp in E
exists l, v, reg
split ; exact Hl |
split ; exact Hm |
split ; | exact Hb
split ; exact E | exact Hlive
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The setter's triple
The Iris instance of the registry and locale_wi.
The expressions of the language.
setlocale(c, p)'s triple over the locale world, from wp_lend and locale_set_return: owning every category's name, the codec piece and the string at p, which vc and vp read as, the call lends every category's new name for good, gives the codec piece a new codec c', which is the world's from then on (codec_current), and binds d to null or c's new name.
Proof 36 steps Qed
LocaleLogicOn over a Logic instance of its own.