 ⊢ R) yields (Γ - {P} ⊢ P → R). This is mechanics of the deduction
-- theorem.
discharge :: (Ord a, Show a) => Term a -> Proof a -> Proof a
discharge asm = d
    where d pr@(Assume t) | t == asm  = UseTheorem (inst (const t) truthThm)
                          | otherwise =
                              MP (UseTheorem (inst2 (concl pr) asm axiom1)) pr
          d pr@(UseTheorem t) =
                MP (UseTheorem (inst2 (concl pr) asm axiom1)) pr
          d (MP imp p) =
                let p' = concl p
                in case concl imp of
                  p'' :=>: r' | p' == p''->
                    MP (MP (UseTheorem (inst3 asm p' r' axiom2)) (d imp)) (d p)
                  _ -> error ("Discharge MP:" ++ show [concl imp, p'])

-- | Verify a proof. If there is only one assumption remaining, we automatically
-- discharge it.
verify :: (Ord a, Show a) 
discharge :: (Ord a, Show a) => Term a -> Proof a -> Proof a
discharge asm = d
    where d pr@(Assume t) | t == asm  = UseTheorem (inst (const t) truthThm)
                          | otherwise =
                              MP (UseTheorem (inst2 (concl pr) asm axiom1)) pr
          d pr@(UseTheorem t) =
                MP (UseTheorem (inst2 (concl pr) asm axiom1)) pr
          d (MP imp p) =
                let p' = concl p
                in case concl imp of
                  p'' :=>: r' | p' == p''->
                    MP (MP (UseTheorem (inst3 asm p' r' axiom2)) (d imp)) (d p)
                  _ -> error ("Discharge MP:" ++ show [concl imp, p'])

-- | Verify a proof. If there is only one assumption remaining, we automatically
-- discharge it.
discharge asm = d
    where d pr@(Assume t) | t == asm  = UseTheorem (inst (const t) truthThm)
                          | otherwise =
                              MP (UseTheorem (inst2 (concl pr) asm axiom1)) pr
          d pr@(UseTheorem t) =
                MP (UseTheorem (inst2 (concl pr) asm axiom1)) pr
          d (MP imp p) =
                let p' = concl p
                in case concl imp of
                  p'' :=>: r' | p' == p''->
                    MP (MP (UseTheorem (inst3 asm p' r' axiom2)) (d imp)) (d p)
                  _ -> error ("Discharge MP:" ++ show [concl imp, p'])

-- | Verify a proof. If there is only one assumption remaining, we automatically
-- discharge it.