module Main %default total -- An expensive function. qib : Nat -> Nat qib Z = 1 qib (S Z) = 2 qib (S (S n)) = qib n * qib (S n) -- An equality whose size reflects the size of numbers. data equals : Nat -> Nat -> Type where eqZ : Z `equals` Z eqS : m `equals` n -> S m `equals` S n eq_refl : {n : Nat} -> n `equals` n eq_refl {n = Z} = eqZ eq_refl {n = S n} = eqS eq_refl -- Here, the proof is very expensive to compute. -- We add a recursive argument to prevent Idris from inlining the function. f : (r, n : Nat) -> Subset Nat (\k => qib n `equals` qib k) f Z n = Element n eq_refl f (S r) n = f r n -- A (contrived) relation, just to have something to show. data represents : Nat -> Nat -> Type where axiom : (n : Nat) -> qib n `represents` n -- Here, the witness is very expensive to compute. -- We add a recursive argument to prevent Idris from inlining the function. g : (r, n : Nat) -> Exists (\k : Nat => k `represents` n) g Z n = Evidence (qib n) (axiom n) g (S r) n = g r n fmt : qib n `represents` n -> String fmt (axiom n) = "axiom " ++ show n main : IO () main = do n <- map (const (the Nat 10000)) (putStrLn "*oink*") putStrLn . show $ getWitness (f 4 n) putStrLn . fmt $ getProof (g 4 n)