⟨ Index | Module NatExamples.SimpleLogLearner
{-# OPTIONS --safe #-}

open import Level hiding (suc)
open import Data.Empty
open import Data.Unit
open import Data.Product
open import Data.Nat as  hiding (_⊔_)
open import Data.Nat.Properties
open import Data.Nat.Logarithm
import Data.Nat.Properties as 
open import Relation.Binary.PropositionalEquality.Core

open import NatLearning
open import Learner-Correctness  F NatLearning-Semantics

open import Utils

module NatExamples.SimpleLogLearner where

-- A learner that guesses a secret k within 2 + 2 * log(k) steps.

bound :   
bound sec = 3 + ⌊log₂ sec  + ⌊log₂ sec 

data SimpleLogLearner : Set where
  [_,∞] : (n : )  SimpleLogLearner
  [_,_] : (n : )  (m : )   SimpleLogLearner

-- instead of commenting on the semantics of above constructors,
-- we directly *define* the semantics:
_⊧_ : SimpleLogLearner    Set
-- Case 1: the secret is greater or equal than 0 (we know nothing)
_⊧_ [ n ,∞] secret = n  secret
_⊧_ [ n , m ] secret = n  secret × secret  m

-- -- Initially, we only know that the secret is ≥ 0
q₀ : SimpleLogLearner
q₀ = [ 0 ,∞]

mid :     
mid n m =  n + m /2⌋

δ : SimpleLogLearner  F  SimpleLogLearner 
δ [ n ,∞] = guess (1 + 2 * n) (1 + 2 * n) 
  { too-low  [ (2 * (suc n)) ,∞]
  ; too-high  [ n , (2 * n) ]
  })
δ [ n , m ] = guess (mid n m) (mid n m) λ
  { too-low  [ suc (mid n m) , m ]
  ; too-high  [ n , pred (mid n m) ]
  }


simple-bisect : Learner 0ℓ
simple-bisect = record
  { C = SimpleLogLearner
  ; R =  -- the game results in natural numbers
  ; q₀ = q₀
  ; learner-on = record { δ = δ }
  }