# New SMT-LIB Code Generation How should the different types of identifiers look in the smt code we generate? What would natural encodings be? There are a million options. We tried to have package data structures only once *per package* rather than *per instance*. Similarly for games. In these cases, game / package type params need to be included. ```smt (declare-const const-proof-{proofname}-{name} {type}) (declare-const const-game-{proofname}-{gameinstname}-{name} {type}) (assert (= const-proof-{proofname}-{name} const-game-{proofname}-{gameinstname}-{name})) ``` This works for consts, but not for state. We can just keep that in a state datatype, bind that to easy names at the start of a function, and then create and return a new state datatype value containing the values of our bound variables. We can even include the available constants in the initial binding: ```smt ; we have talked about this before: ; the package state should not be identified by the package instance, ; but just the package type and the package's type parameters. ; this way we can reuse them better. ; for now, let's ignore the type params in the implementation, ; but keep a notice there to remind us (define-datatype PackageState-{packagename}-{type-params} (mk-PackageState-{pkgname}-{type-params} (PackageState-{pkgname}-{type-params}-T (Array Int Bits_n)))) ; Similar with the game state. ; however, it of course references all the package states by package instance name. (define-datatype GameState-{gamename}-{game-type-params} (mk-GameState-{gamename}-{game-type-params} (GameState-{gamename}-{game-type-params}-{pkginst} PackageState-{pkgname}-{pkg-type-params}) (GameState-{gamename}-{game-type-params}-{mi-pkginst} (Array Integer PackageState-{pkgname}-{pkg-type-params})))) ; the const params of a package. can be shared between different package isntances that use the same type params. (define-datatype PackageConstParams-{pkg-name}-{type-params} (mk-PackageConstParams-{pkgname}-{type-params} ((PackageConstParams-{pkgname}-{type-params}-n Int)))) ; the same for games. (define-datatype GameConstParams-{game-name}-{game-type-params} (mk-GameConstParams-{game-name}-{game-type-params} ((GameConstParams-{game-name}-{game-type-params}-n Int)))) ; this maps the game's parameters to the parameters of a package instance in the game. ; basically it is the smt represenation of the params block in a package instantiation. ; this should also contain the type params of the game and the package in the function name, but i was too lazy to include it. ; the function can be called in (define-function game-pkg-const-param-mapping-{game-name}-{pkg-inst-name} (params GameConstParams-{game-name}) PackageConstParams-{pkg-name} ... ) ; while this is pretty, it doesn't work for function parameters (at least as long as we ; try to be SMT-LIB 2.6-compatible). So what we do here instead is ; - for game-level function params, just declare free functions ; - for package-level function params, define functions that call the game's function ; that is assigned to it in the package instantiation. ; the return type is basically like before (define-datatype OracleReturn-{game-name}-{game-type-params}-{pkg-name}-{pkg-type-params}-{oracle-name} (ok-OracleReturn-{game-name}-{game-type-params}-{pkg-name}-{pkg-type-params}-{oracle-name} (OracleReturn-{game-name}-{game-type-params}-{pkg-name}-{pkg-type-params}-{oracle-name}-gamestate GameState-{game-name}-{game-type-params}) (OracleReturn-{game-name}-{game-type-params}-{pkg-name}-{pkg-type-params}-{oracle-name}-return {type}) abort-OracleReturn-{game-name}-{game-type-params}-{pkg-name}-{pkg-type-params}-{oracle-name}) ; the oracles need to be specific to the the package instance, because the called oracles ; depend on the wires the oracle is connected to. ; Whether it is specific to the game inst depends on how we handle const params. ; If const params are just a bunch of loose globals, we need to be specific because we ; must know which of the loose global to use, and these are specific to the game instances. ; However, if we have a consts struct specific to the game, then we can pass that in and ; extract the values from there. The proof can then pass different values in there ; We can then compute the package const params from the game const params, using the mapping function. (define-fun oracle-{proofname}-{gameinstname}-{pkginstname}-{oracle-name} ((<state> GameState-{game-name}-{game-type-params})) ((<game-consts> GameConstParams-{game-name}-{game-type-params})) OracleReturn-{game-name}-{game-type-params}-{pkg-inst-name}-{pkg-type-params}-{oracle-name} (let* ( ; I am not sure if SMT-LIB has 'let*' --- the idea is that we can reference values bound within the let header (<pkg-consts> (game-pkg-const-param-mapping-{game-name}-{pkg-inst-name} <game-consts>)) (T (PackageState-{pkgname}-{type-params} (GameState-{gameinstname}-T state))) (n (PackageConstParams-{pkgname}-{type-params}-n <pkg-consts>))) (... (let ((x ...)) (... (ok-OracleReturn-{pkgname}-{typeconst} (mk-GameState-{gameinstname} (mk-PackageState-{pkgname}-{typeparams} T)) x)))))) ; This explores multi instance indices. This code hasn't been ported to use the game const params struct, it still uses the globals. ; Hence, it is still specific to the game instance. (define-fun mi-oracle-{proofname}-{game-inst-name}-{mi-pkg-inst-name}-{oracle-name} ( (<state> GameState-{game-inst-name}) (<mi-idx> Integer)) OracleReturn-{game-inst-name}-{mi-pkg-inst-name}-{oracle-name} (let ( (T (PackageState-{pkg-name}-{type-params}-T (select (GameState-{game-inst-name}-{mi-pkg-inst-name} <state>))) <mi-idx>) (n game-{proof-name}-{game-inst-name}-const-n)) (... (let ((x ...)) (... (ok-OracleReturn-{pkgname}-{typeconst} (mk-GameState-{gameinstname} (store GameState-{game-inst-name}-{mi-pkg-inst-name} <mi-idx> (mk-PackageState-{pkg-name}-{type-params} T))) x)))))) ``` Where we use `<name>` for system variables, so they can't collide with user variables ## Action Items - [ ] Implement generating Package Const instantiation functions - [ ] Bind Package Consts at oracle start - [ ] Use plain variable names for consts in oracle code - [ ] Implement proof -> game inst const instantiation code