tip-lib-0.1: src/Tip/Pass/AxiomatizeFuncdefs.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Tip.Pass.AxiomatizeFuncdefs where
#include "errors.h"
import Tip.Core
import Tip.Fresh
import Data.Generics.Geniplate
import Control.Applicative
--conProjs :: Project a => Global a -> [Global a]
conProjs = undefined
{- (Global k (PolyType tvs arg_tys res_ty) ts _)
= [ Global (project k i) (PolyType tvs [res_ty] arg_ty) ts ProjectNS
| (i,arg_ty) <- zip [0..] arg_tys
]
-}
axiomatizeFuncdefs :: Theory a -> Theory a
axiomatizeFuncdefs thy@Theory{..} =
thy{
thy_funcs = [],
thy_sigs = thy_sigs ++ abs,
thy_asserts = fms ++ thy_asserts
}
where
(abs,fms) = unzip (map axiomatize thy_funcs)
-- Passes needed afterwards:
--
-- 1) x = e ==> F[x] ~~> F[e]
--
-- 2)
-- all x (D => (all y . E) /\ (all z . F))
-- ~~>
-- all x ((D => all y . E) /\ (D => all z . F))
-- ~~>
-- (all x y (D => E)) /\ (all x z (D => F))
--
-- (TODO)
axiomatize :: forall a . Function a -> (Signature a, Formula a)
axiomatize fn@Function{..} =
( Signature func_name (funcType fn)
, Formula Assert func_tvs (ax func_body)
)
where
lhs = applyFunction fn (map TyVar func_tvs) (map Lcl func_args)
ax :: Expr a -> Expr a
ax e0 = case e0 of
Match s (Case Default def_rhs:alts) -> invert_alts s alts def_rhs /\ ax_alts s alts
Match s alts -> ax_alts s alts
Let{} -> __ -- could use ==> while Let is neither recursive nor polymorphic
Lam{} -> __
Quant{} -> __
_ -> lhs === e0 -- e0 should now only be (:@:) and Lcl
where
invert_alts :: Expr a -> [Case a] -> Expr a -> Expr a
invert_alts _ [] def_rhs = def_rhs
invert_alts s (Case pat _:alts) def_rhs = s === invert_pat s pat \/
invert_alts s alts def_rhs
where
invert_pat :: Expr a -> Pattern a -> Expr a
invert_pat _ Default = __
invert_pat _ (LitPat lit) = literal lit
invert_pat s (ConPat k _) = Gbl k :@: [ Gbl p :@: [s] | p <- conProjs k ]
ax_alts :: Expr a -> [Case a] -> Expr a
ax_alts s alts = ands [ ax_pat s pat rhs | Case pat rhs <- alts ]
where
ax_pat :: Expr a -> Pattern a -> Expr a -> Expr a
ax_pat _ Default _ = __
ax_pat s (LitPat lit) rhs = s === literal lit ==> ax rhs
ax_pat s (ConPat k bs) rhs = mkQuant Forall bs
(s === Gbl k :@: map Lcl bs ==> ax rhs)