Theory DG_Spec
theory DG_Spec
imports DG_Manager "Voblint_CFG.CFG_Def"
begin
section ‹What an analysis supplies: manager-native transfers›
text ‹
An analysis supplies one manager-native transfer per edge action and the
pieces of the call/return protocol. A transfer takes a ‹man› and returns
a ‹strategy_program›: global reads are ‹man_global› calls, global
publications are ‹man_sideg› calls, and a transfer that makes neither
compiles to a tree with no ‹QueryG› and no ‹Side› at all. This replaces the
state-threading shape ‹'dl ⇒ 'dg ⇒ 'dg × 'dl›, which forced every transfer to
republish the global it read even where the global channel is provably inert.
What a program answers with depends on the field. An edge transfer and a
combine stage answer the successor local value, so their compiled tree is an
equation's right-hand side outright. Entry answers a list of alternatives
instead, which no equation carries: the routed call program consumes that list,
running one activation and return combine per alternative and joining what
they contribute.
There is one interface here, not a hierarchy of them. A specification is
∗‹local-only› when every field is a pure function of the values it is handed
--- ‹local_transfer› for the edge fields, ‹local_enter_transfer› for entry ---
and ∗‹effectful› when some field reads or publishes through
‹man_global›/‹man_sideg›. Those words describe what a given specification's
compiled trees do, and are read off those trees -- they are not a
classification the framework branches on.
›
text ‹
An ‹analysis_event› is an analyzer-visible occurrence distinct from an ordinary
control-flow transfer: a domain may observe it, but it must not by itself refine
execution. The channel mirrors Goblint's separation of its ordinary ‹Spec›
transfer methods (‹assign›/‹branch›/‹skip›/...) from ‹Spec.event›. The
check itself does not: Goblint handles ‹__goblint_check› in ‹special›, as
the library description ‹Assert {check = true; refine = false}›, and its
‹Events.Assert› is emitted only by the ‹abortUnless› analysis and refines
the state in Base (goblint/analyzer ‹5320a6b7›: ‹libraryFunctions.ml›,
‹assert.ml›, ‹base.ml›). Voblint's sole current event is a check's
condition, which never refines; the
vocabulary is deliberately left open rather than pre-populated, so that a future
VIMP source construct with no current counterpart (e.g. a diagnostic-only
annotation) adds a constructor here instead of a new specification field. A
construct that narrows feasible execution, such as ‹assume›, is not a
candidate: it belongs on ‹dgs_branch› or on a new refining field, not here.
It is declared here, beside the ‹dgs_event› field it types, because the
specification record and the edge-action dispatcher that feeds it are the only
things that ever case on it.
›
datatype analysis_event =
Check_Event check_label exp