Caching Queries Made by a Computation #
This file defines a modifier QueryImpl.withCaching that modifies a query implementation to
cache results to return to the same query in the future.
We also define cachingOracle, which caches queries to the oracles in spec,
querying fresh values from spec if no cached value exists.
Modify a query implementation to cache previous call and return that output in the future.
Instances For
Running withCaching at state cache produces a result whose cache is ≥ cache.
On a cache hit the state is unchanged; on a miss a single entry is added.
withCaching preserves the invariant (cache₀ ≤ ·) (the cache only grows).
Oracle for caching queries to the oracles in spec, querying fresh values if needed.
Instances For
Trivially true via probFailure_eq_zero since both sides are OracleComp computations.
A generic withCaching version for arbitrary base monads would require a separate argument
because caching changes the oracle semantics (cache hits skip the underlying oracle call).
Trivially true via probFailure_eq_zero; see probFailure_run_simulateQ.
Run an OracleComp with a QueryCache as a priority layer over the real oracle.
Cached entries are returned directly (no oracle query), misses fall through to the real
oracle and get cached for subsequent lookups within the same computation.
This is the fundamental "programmable random oracle" primitive: pre-fill the cache with programmed entries, then run the computation. Concretely:
withCacheOverlay cache oa = StateT.run' (simulateQ cachingOracle oa) cache
Key properties:
withCacheOverlay ∅ oadeduplicates queries but is otherwise equivalent tooa.withCacheOverlay cache (query t)returnsvwithout an external query whencache t = some v, and queries the real oracle whencache t = none.
TODO: generalize FiatShamir.runtime to runtimeWithCache cache with
runtime = runtimeWithCache ∅, deriving randomOracle evaluation from
withCacheOverlay + evalDist.
Instances For
simulateQ cachingOracle only grows the cache: for any oa, if
z ∈ support ((simulateQ cachingOracle oa).run cache₀) then cache₀ ≤ z.2.
After running cachingOracle on a single query at t, the resulting cache
maps t to the returned value.