{-# OPTIONS --safe #-}

open import Algebra              using (CommutativeMonoid)
open import Data.Nat.Properties  using (+-0-monoid)
import Data.Maybe as M
import Data.Sum.Relation.Unary.All as Sum

import Data.Integer as 
import Data.Rational as 

open import Tactic.Derive.DecEq

open import Ledger.Prelude
open import Ledger.Conway.Abstract
open import Ledger.Conway.Transaction

module Ledger.Conway.Conformance.Utxo
  (txs : _) (open TransactionStructure txs)
  (abs : AbstractFunctions txs) (open AbstractFunctions abs)
  where

open import Ledger.Conway.ScriptValidation txs abs
open import Ledger.Conway.Fees txs using (scriptsCost)
open import Ledger.Conway.Conformance.Certs govStructure

private
  module L where
    open import Ledger.Conway.Utxo txs abs public

open PParams

instance
  _ = +-0-monoid

open L public using (UTxOEnv; UTxOState; ⟦_,_,_,_⟧ᵘ; HasCast-UTxOState; updateDeposits
                    ; cbalance; balance; depositRefunds; consumed
                    ; produced; outs; newDeposits; refScriptsSize )

private variable
  Γ : UTxOEnv
  s s' : UTxOState
  tx : Tx

open PParams

data _⊢_⇀⦇_,UTXOS⦈_ : UTxOEnv  UTxOState  Tx  UTxOState  Type where
  Scripts-Yes :
     {Γ} {s} {tx}
     let open Tx tx renaming (body to txb); open TxBody txb
          open UTxOEnv Γ renaming (pparams to pp)
          open UTxOState s
          sLst = collectPhaseTwoScriptInputs pp tx utxo
      in
         evalScripts tx sLst  isValid
         isValid  true
          ────────────────────────────────
          Γ  s ⇀⦇ tx ,UTXOS⦈  $\begin{pmatrix} (\,\href{Ledger.Conway.Utxo.html#2811}{\htmlId{1570}{\htmlClass{Function}{\text{utxo}}}}\, \,\href{Axiom.Set.Map.html#10748}{\htmlId{1575}{\htmlClass{Function Operator}{\text{∣}}}}\, \,\href{Ledger.Conway.Transaction.html#2798}{\htmlId{1577}{\htmlClass{Function}{\text{txins}}}}\, \,\href{Axiom.Set.Map.html#10748}{\htmlId{1583}{\htmlClass{Function Operator}{\text{ᶜ}}}}\,) \,\href{Axiom.Set.Map.html#6320}{\htmlId{1586}{\htmlClass{Function Operator}{\text{∪ˡ}}}}\, (\,\href{Ledger.Conway.Utxo.html#3525}{\htmlId{1590}{\htmlClass{Function}{\text{L.outs}}}}\, \,\href{Ledger.Conway.Conformance.Utxo.html#1264}{\htmlId{1597}{\htmlClass{Field}{\text{txb}}}}\,)
                              \\ \,\href{Ledger.Conway.Utxo.html#2833}{\htmlId{1634}{\htmlClass{Function}{\text{fees}}}}\, \,\href{Class.HasAdd.Core.html#162}{\htmlId{1639}{\htmlClass{Field Operator}{\text{+}}}}\, \,\href{Ledger.Conway.Transaction.html#2892}{\htmlId{1641}{\htmlClass{Function}{\text{txfee}}}}\,
                              \\ \,\href{Ledger.Conway.Utxo.html#2855}{\htmlId{1679}{\htmlClass{Function}{\text{deposits}}}}\,
                              \\ \,\href{Ledger.Conway.Utxo.html#2881}{\htmlId{1720}{\htmlClass{Function}{\text{donations}}}}\, \,\href{Class.HasAdd.Core.html#162}{\htmlId{1730}{\htmlClass{Field Operator}{\text{+}}}}\, \,\href{Ledger.Conway.Transaction.html#3134}{\htmlId{1732}{\htmlClass{Function}{\text{txdonation}}}}\,
                              \end{pmatrix}$

  Scripts-No :
     {Γ} {s} {tx}
     let open Tx tx renaming (body to txb); open TxBody txb
          open UTxOEnv Γ renaming (pparams to pp)
          open UTxOState s
          sLst = collectPhaseTwoScriptInputs pp tx utxo
      in
         evalScripts tx sLst  isValid
         isValid  false
          ────────────────────────────────
          Γ  s ⇀⦇ tx ,UTXOS⦈  $\begin{pmatrix} \,\href{Ledger.Conway.Utxo.html#2811}{\htmlId{2155}{\htmlClass{Function}{\text{utxo}}}}\, \,\href{Axiom.Set.Map.html#10748}{\htmlId{2160}{\htmlClass{Function Operator}{\text{∣}}}}\, \,\href{Ledger.Conway.Transaction.html#3358}{\htmlId{2162}{\htmlClass{Function}{\text{collateral}}}}\, \,\href{Axiom.Set.Map.html#10748}{\htmlId{2173}{\htmlClass{Function Operator}{\text{ᶜ}}}}\,
                              \\ \,\href{Ledger.Conway.Utxo.html#2833}{\htmlId{2207}{\htmlClass{Function}{\text{fees}}}}\, \,\href{Class.HasAdd.Core.html#162}{\htmlId{2212}{\htmlClass{Field Operator}{\text{+}}}}\, \,\href{Ledger.Conway.Utxo.html#3685}{\htmlId{2214}{\htmlClass{Function}{\text{L.cbalance}}}}\, (\,\href{Ledger.Conway.Utxo.html#2811}{\htmlId{2226}{\htmlClass{Function}{\text{utxo}}}}\, \,\href{Axiom.Set.Map.html#10678}{\htmlId{2231}{\htmlClass{Function Operator}{\text{∣}}}}\, \,\href{Ledger.Conway.Transaction.html#3358}{\htmlId{2233}{\htmlClass{Function}{\text{collateral}}}}\,)
                              \\ \,\href{Ledger.Conway.Utxo.html#2855}{\htmlId{2277}{\htmlClass{Function}{\text{deposits}}}}\,
                              \\ \,\href{Ledger.Conway.Utxo.html#2881}{\htmlId{2318}{\htmlClass{Function}{\text{donations}}}}\,
                              \end{pmatrix}$

unquoteDecl Scripts-Yes-premises = genPremises Scripts-Yes-premises (quote Scripts-Yes)
unquoteDecl Scripts-No-premises  = genPremises Scripts-No-premises  (quote Scripts-No)

data _⊢_⇀⦇_,UTXO⦈_ : UTxOEnv  UTxOState  Tx  UTxOState  Type where

  UTXO-inductive :
    let open Tx tx renaming (body to txb); open TxBody txb
        open UTxOEnv Γ renaming (pparams to pp)
        open UTxOState s
        txoutsʰ = (mapValues txOutHash txouts)
        overhead = 160
    in
     txins                                 txins  refInputs  dom utxo
     txins  refInputs                     L.inInterval slot txvldt
     L.feesOK pp tx utxo                     L.consumed pp s txb  L.produced pp s txb
     coin mint  0                           txsize  maxTxSize pp
     L.refScriptsSize utxo tx  pp .maxRefScriptSizePerTx

     ∀[ (_ , txout)   txoutsʰ  ]
        inject ((overhead + L.utxoEntrySize txout) * coinsPerUTxOByte pp) ≤ᵗ getValueʰ txout
     ∀[ (_ , txout)   txoutsʰ  ]
        serSize (getValueʰ txout)  maxValSize pp
     ∀[ (a , _)  range txoutsʰ ]
        Sum.All (const )  a  a .BootstrapAddr.attrsSize  64) a
     ∀[ (a , _)  range txoutsʰ ]  netId a          NetworkId
     ∀[ a  dom txwdrls ]          NetworkIdOf a    NetworkId
     txNetworkId ~ just NetworkId
     curTreasury ~ just treasury
     Γ  s ⇀⦇ tx ,UTXOS⦈ s'
      ────────────────────────────────
      Γ  s ⇀⦇ tx ,UTXO⦈ s'

pattern UTXO-inductive⋯ tx Γ s x y z w k l m v j n o p q r t u h
      = UTXO-inductive {tx}{Γ}{s} (x , y , z , w , k , l , m , v , j , n , o , p , q , r , t , u , h)
unquoteDecl UTXO-premises = genPremises UTXO-premises (quote UTXO-inductive)