@@ -13,6 +13,7 @@ import Core.Evaluate
13import Control.Monad
13import Control.Monad
14import Control.Monad.State
14import Control.Monad.State
15import Data.List
15import Data.List
16import Debug.Trace
17import Debug.Trace
18-- Data to pass to recursively called elaborators; e.g. for where blocks,
19-- Data to pass to recursively called elaborators; e.g. for where blocks,
@@ -772,22 +773,76 @@ runTac autoSolve ist tac = do env <- get_env
772 runT Solve = solve
773 runT Solve = solve
773 runT (Try l r) = do try' (runT l) (runT r) True
774 runT (Try l r) = do try' (runT l) (runT r) True
774 runT (TSeq l r) = do runT l; runT r
775 runT (TSeq l r) = do runT l; runT r
776+ runT (ApplyTactic tm) = do tenv <- get_env -- store the environment before it is loaded with junk
775− runT (ReflectTac tm) = do attack -- let x : Tactic = tm in ...
777+ attack -- let f : List (TTName, Binder TT) -> Tactic = tm in ...
776− valn <- unique_hole (MN 0 "tacval")
778+ valn <- unique_hole (MN 0 "tacval")
777− claim valn (Var tacticTy)
779+ claim valn (RBind (UN "__pi_arg")
780+ (Pi (RApp listTy envTupleType)) tacticTy)
778− tacn <- unique_hole (MN 0 "tacn")
781+ tacn <- unique_hole (MN 0 "tacn")
779− letbind tacn (Var tacticTy) (Var valn)
782+ letbind tacn (RBind (UN "__pi_arg")
783+ (Pi (RApp listTy envTupleType)) tacticTy)
780− focus valn
785+ focus valn
781− elab ist toplevel False False (MN 0 "tac") tm
786+ elab ist toplevel False False (MN 0 "tac") tm
782− (tm', ty') <- get_type_val (Var tacn)
787+ (tm', ty') <- get_type_val (Var tacn)
783− ctxt <- get_context
788+ ctxt <- get_context
784− env <- get_env
789+ env <- get_env
785− let tactic = normalise ctxt env tm'
790+ let tm'' = normalise ctxt env tm'
791+ attack -- let x : List (TTName, Binder TT) = reflectEnv in ...
792+ envval <- unique_hole (MN 0 "letval")
793+ claim envval (RApp listTy envTupleType)
794+ letn <- unique_hole (MN 0 "letvar")
795+ letbind letn (RApp listTy envTupleType) (Var envval)
798+ elab ist toplevel False False (MN 0 "tac") (PQuote (reflectEnv tenv))
799+ (env', _) <- get_type_val (Var letn)
802+ let env'' = normalise ctxt env env'
803+ attack -- let z : Tactic = f x
804+ restac <- unique_hole (MN 0 "letval")
805+ claim restac tacticTy
806+ letn <- unique_hole (MN 0 "letvar")
807+ letbind letn tacticTy (Var restac)
809+ elab ist toplevel False False (MN 0 "tac") (PQuote (RApp (forget tm'') (forget env'')))
810+ (res, _) <- get_type_val (Var letn)
813+ let tactic = normalise ctxt env res
786− runReflected tactic
814+ runReflected tactic
788−-- trace (show p ++ "\n\n") $
790− where tacticTy = tacm "Tactic"
815+ where tacticTy = Var (reflm "Tactic")
816+ listTy = Var (NS (UN "List") ["List", "Prelude"])
817+ runT (Reflect v) = do attack -- let x = reflect v in ...
818+ tyn <- unique_hole (MN 0 "letty")
820+ valn <- unique_hole (MN 0 "letval")
821+ claim valn (Var tyn)
822+ letn <- unique_hole (MN 0 "letvar")
823+ letbind letn (Var tyn) (Var valn)
825+ elab ist toplevel False False (MN 0 "tac") v
826+ (value, _) <- get_type_val (Var letn)
829+ let value' = hnf ctxt env value
830+ runTac autoSolve ist (Exact $ PQuote (reflect value'))
831+ runT (Fill v) = do attack -- let x = fill x in ...
832+ tyn <- unique_hole (MN 0 "letty")
834+ valn <- unique_hole (MN 0 "letval")
835+ claim valn (Var tyn)
836+ letn <- unique_hole (MN 0 "letvar")
837+ letbind letn (Var tyn) (Var valn)
839+ elab ist toplevel False False (MN 0 "tac") v
840+ (value, _) <- get_type_val (Var letn)
843+ let value' = normalise ctxt env value
844+ rawValue <- reifyRaw value'
845+ runTac autoSolve ist (Exact $ PQuote rawValue)
791 runT (GoalType n tac) = do g <- goal
846 runT (GoalType n tac) = do g <- goal
792 case unApply g of
847 case unApply g of
793 (P _ n' _, _) ->
848 (P _ n' _, _) ->
@@ -797,24 +852,351 @@ runTac autoSolve ist tac = do env <- get_env
797 _ -> fail "Wrong goal type"
852 _ -> fail "Wrong goal type"
798 runT x = fail $ "Not implemented " ++ show x
853 runT x = fail $ "Not implemented " ++ show x
800− runReflected t = do t' <- reify t
855+ runReflected t = do t' <- reify ist t
801 runTac autoSolve ist t'
856 runTac autoSolve ist t'
802− tacm n = NS (UN n) ["Reflection", "Language"]
857+
803−
858+-- | Prefix a name with the "Reflection.Language" namespace
804− reify :: Term -> ElabD PTactic
859+reflm :: String -> Name
805− reify (P _ n _) | n == tacm "Trivial" = return Trivial
860+reflm n = NS (UN n) ["Reflection", "Language"]
806− reify (P _ n _) | n == tacm "Solve" = return Solve
861+
807− reify f@(App _ _)
862+
808− | (P _ f _, args) <- unApply f = reifyAp f args
863+-- | Reify tactics from their reflected representation
809− reify t = fail ("Unknown tactic " ++ show t)
864+reify :: IState -> Term -> ElabD PTactic
810−
865+reify _ (P _ n _) | n == reflm "Intros" = return Intros
811− reifyAp t [l, r] | t == tacm "Try" = liftM2 Try (reify l) (reify r)
866+reify _ (P _ n _) | n == reflm "Trivial" = return Trivial
812− reifyAp t [Constant (Str x)]
867+reify _ (P _ n _) | n == reflm "Solve" = return Solve
813− | t == tacm "Refine" = return $ Refine (UN x) []
868+reify _ (P _ n _) | n == reflm "Compute" = return Compute
814− reifyAp t [l, r] | t == tacm "Seq" = liftM2 TSeq (reify l) (reify r)
869+reify ist t@(App _ _)
815− reifyAp t [Constant (Str n), x]
870+ | (P _ f _, args) <- unApply t = reifyApp ist f args
816− | t == tacm "GoalType" = liftM (GoalType n) (reify x)
871+reify _ t = fail ("Unknown tactic " ++ show t)
817− reifyAp f args = fail ("Unknown tactic " ++ show (f, args)) -- shouldn't happen
872+
873+reifyApp :: IState -> Name -> [Term] -> ElabD PTactic
874+reifyApp ist t [l, r] | t == reflm "Try" = liftM2 Try (reify ist l) (reify ist r)
876+ | t == reflm "Refine" = do n <- reifyTTName x
877+ return $ Refine n []
878+reifyApp ist t [l, r] | t == reflm "Seq" = liftM2 TSeq (reify ist l) (reify ist r)
879+reifyApp ist t [Constant (Str n), x]
880+ | t == reflm "GoalType" = liftM (GoalType n) (reify ist x)
881+reifyApp _ t [Constant (Str n)]
882+ | t == reflm "Intro" = return $ Intro [UN n]
884+ | t == reflm "ApplyTactic" = liftM (ApplyTactic . delab ist) (reifyTT t')
886+ | t == reflm "Reflect" = liftM (Reflect . delab ist) (reifyTT t')
888+ | t == reflm "Fill" = liftM (Fill . PQuote) (reifyRaw t')
890+ | t == reflm "Exact" = liftM (Exact . delab ist) (reifyTT t')
892+ | t == reflm "Focus" = liftM Focus (reifyTTName x)
894+ | t == reflm "Rewrite" = liftM (Rewrite . delab ist) (reifyTT t')
895+reifyApp ist t [n, t']
896+ | t == reflm "LetTac" = do n' <- reifyTTName n
898+ return $ LetTac n' (delab ist t')
899+reifyApp ist t [n, tt', t']
900+ | t == reflm "LetTacTy" = do n' <- reifyTTName n
903+ return $ LetTacTy n' (delab ist tt'') (delab ist t'')
904+reifyApp _ f args = fail ("Unknown tactic " ++ show (f, args)) -- shouldn't happen
906+-- | Reify terms from their reflected representation
907+reifyTT :: Term -> ElabD Term
909+ | (P _ f _, args) <- unApply t = reifyTTApp f args
911+ | n == reflm "Erased" = return $ Erased
913+ | n == reflm "Impossible" = return $ Impossible
914+reifyTT t = fail ("Unknown reflection term: " ++ show t)
916+reifyTTApp :: Name -> [Term] -> ElabD Term
917+reifyTTApp t [nt, n, x]
918+ | t == reflm "P" = do nt' <- reifyTTNameType nt
921+ return $ P nt' n' x'
922+reifyTTApp t [Constant (I i)]
923+ | t == reflm "V" = return $ V i
924+reifyTTApp t [n, b, x]
925+ | t == reflm "Bind" = do n' <- reifyTTName n
926+ b' <- reifyTTBinder reifyTT (reflm "TT") b
928+ return $ Bind n' b' x'
930+ | t == reflm "App" = do f' <- reifyTT f
934+ | t == reflm "TConst" = liftM Constant (reifyTTConst c)
935+reifyTTApp t [t', Constant (I i)]
936+ | t == reflm "Proj" = do t'' <- reifyTT t'
939+ | t == reflm "TType" = liftM TType (reifyTTUExp tt)
940+reifyTTApp t args = fail ("Unknown reflection term: " ++ show (t, args))
942+-- | Reify raw terms from their reflected representation
943+reifyRaw :: Term -> ElabD Raw
945+ | (P _ f _, args) <- unApply t = reifyRawApp f args
947+ | n == reflm "RType" = return $ RType
948+reifyRaw t = fail ("Unknown reflection raw term: " ++ show t)
950+reifyRawApp :: Name -> [Term] -> ElabD Raw
952+ | t == reflm "Var" = liftM Var (reifyTTName n)
953+reifyRawApp t [n, b, x]
954+ | t == reflm "RBind" = do n' <- reifyTTName n
955+ b' <- reifyTTBinder reifyRaw (reflm "Raw") b
957+ return $ RBind n' b' x'
959+ | t == reflm "RApp" = liftM2 RApp (reifyRaw f) (reifyRaw x)
961+ | t == reflm "RForce" = liftM RForce (reifyRaw t')
963+ | t == reflm "RConstant" = liftM RConstant (reifyTTConst c)
964+reifyRawApp t args = fail ("Unknown reflection raw term: " ++ show (t, args))
966+reifyTTName :: Term -> ElabD Name
967+reifyTTName t@(App _ _)
968+ | (P _ f _, args) <- unApply t = reifyTTNameApp f args
969+reifyTTName t = fail ("Unknown reflection term name: " ++ show t)
971+reifyTTNameApp :: Name -> [Term] -> ElabD Name
972+reifyTTNameApp t [Constant (Str n)]
973+ | t == reflm "UN" = return $ UN n
974+reifyTTNameApp t [n, ns]
975+ | t == reflm "NS" = do n' <- reifyTTName n
976+ ns' <- reifyTTNamespace ns
978+reifyTTNameApp t [Constant (I i), Constant (Str n)]
979+ | t == reflm "MN" = return $ MN i n
981+ | t == reflm "NErased" = return NErased
982+reifyTTNameApp t args = fail ("Unknown reflection term name: " ++ show (t, args))
984+reifyTTNamespace :: Term -> ElabD [String]
985+reifyTTNamespace t@(App _ _)
987+ (P _ f _, [Constant StrType])
988+ | f == NS (UN "Nil") ["List", "Prelude"] -> return []
989+ (P _ f _, [Constant StrType, Constant (Str n), ns])
990+ | f == NS (UN "::") ["List", "Prelude"] -> liftM (n:) (reifyTTNamespace ns)
991+ _ -> fail ("Unknown reflection namespace arg: " ++ show t)
992+reifyTTNamespace t = fail ("Unknown reflection namespace arg: " ++ show t)
994+reifyTTNameType :: Term -> ElabD NameType
995+reifyTTNameType t@(P _ n _) | n == reflm "Bound" = return $ Bound
996+reifyTTNameType t@(P _ n _) | n == reflm "Ref" = return $ Ref
997+reifyTTNameType t@(App _ _)
999+ (P _ f _, [Constant (I tag), Constant (I num)])
1000+ | f == reflm "DCon" -> return $ DCon tag num
1001+ | f == reflm "TCon" -> return $ TCon tag num
1002+ _ -> fail ("Unknown reflection name type: " ++ show t)
1003+reifyTTNameType t = fail ("Unknown reflection name type: " ++ show t)
1005+reifyTTBinder :: (Term -> ElabD a) -> Name -> Term -> ElabD (Binder a)
1006+reifyTTBinder reificator binderType t@(App _ _)
1007+ = case unApply t of
1008+ (P _ f _, bt:args) | forget bt == Var binderType
1009+ -> reifyTTBinderApp reificator f args
1010+ _ -> fail ("Mismatching binder reflection: " ++ show t)
1011+reifyTTBinder _ _ t = fail ("Unknown reflection binder: " ++ show t)
1013+reifyTTBinderApp :: (Term -> ElabD a) -> Name -> [Term] -> ElabD (Binder a)
1014+reifyTTBinderApp reif f [t]
1015+ | f == reflm "Lam" = liftM Lam (reif t)
1016+reifyTTBinderApp reif f [t]
1017+ | f == reflm "Pi" = liftM Pi (reif t)
1018+reifyTTBinderApp reif f [x, y]
1019+ | f == reflm "Let" = liftM2 Let (reif x) (reif y)
1020+reifyTTBinderApp reif f [x, y]
1021+ | f == reflm "NLet" = liftM2 NLet (reif x) (reif y)
1022+reifyTTBinderApp reif f [t]
1023+ | f == reflm "Hole" = liftM Hole (reif t)
1024+reifyTTBinderApp reif f [t]
1025+ | f == reflm "GHole" = liftM GHole (reif t)
1026+reifyTTBinderApp reif f [x, y]
1027+ | f == reflm "Guess" = liftM2 Guess (reif x) (reif y)
1028+reifyTTBinderApp reif f [t]
1029+ | f == reflm "PVar" = liftM PVar (reif t)
1030+reifyTTBinderApp reif f [t]
1031+ | f == reflm "PVTy" = liftM PVTy (reif t)
1032+reifyTTBinderApp _ f args = fail ("Unknown reflection binder: " ++ show (f, args))
1034+reifyTTConst :: Term -> ElabD Const
1035+reifyTTConst (P _ n _) | n == reflm "IType" = return $ IType
1036+reifyTTConst (P _ n _) | n == reflm "BIType" = return $ BIType
1037+reifyTTConst (P _ n _) | n == reflm "FlType" = return $ FlType
1038+reifyTTConst (P _ n _) | n == reflm "ChType" = return $ ChType
1039+reifyTTConst (P _ n _) | n == reflm "StrType" = return $ StrType
1040+reifyTTConst (P _ n _) | n == reflm "B8Type" = return $ B8Type
1041+reifyTTConst (P _ n _) | n == reflm "B16Type" = return $ B16Type
1042+reifyTTConst (P _ n _) | n == reflm "B32Type" = return $ B32Type
1043+reifyTTConst (P _ n _) | n == reflm "B64Type" = return $ B64Type
1044+reifyTTConst (P _ n _) | n == reflm "PtrType" = return $ PtrType
1045+reifyTTConst (P _ n _) | n == reflm "VoidType" = return $ VoidType
1046+reifyTTConst (P _ n _) | n == reflm "Forgot" = return $ Forgot
1047+reifyTTConst t@(App _ _)
1048+ | (P _ f _, [arg]) <- unApply t = reifyTTConstApp f arg
1049+reifyTTConst t = fail ("Unknown reflection constant: " ++ show t)
1051+reifyTTConstApp :: Name -> Term -> ElabD Const
1052+reifyTTConstApp f (Constant c@(I _))
1053+ | f == reflm "I" = return $ c
1054+reifyTTConstApp f (Constant c@(BI _))
1055+ | f == reflm "BI" = return $ c
1056+reifyTTConstApp f (Constant c@(Fl _))
1057+ | f == reflm "Fl" = return $ c
1058+reifyTTConstApp f (Constant c@(I _))
1059+ | f == reflm "Ch" = return $ c
1060+reifyTTConstApp f (Constant c@(Str _))
1061+ | f == reflm "Str" = return $ c
1062+reifyTTConstApp f (Constant c@(B8 _))
1063+ | f == reflm "B8" = return $ c
1064+reifyTTConstApp f (Constant c@(B16 _))
1065+ | f == reflm "B16" = return $ c
1066+reifyTTConstApp f (Constant c@(B32 _))
1067+ | f == reflm "B32" = return $ c
1068+reifyTTConstApp f (Constant c@(B64 _))
1069+ | f == reflm "B64" = return $ c
1070+reifyTTConstApp f arg = fail ("Unknown reflection constant: " ++ show (f, arg))
1072+reifyTTUExp :: Term -> ElabD UExp
1073+reifyTTUExp t@(App _ _)
1074+ = case unApply t of
1075+ (P _ f _, [Constant (I i)]) | f == reflm "UVar" -> return $ UVar i
1076+ (P _ f _, [Constant (I i)]) | f == reflm "UVal" -> return $ UVal i
1077+ _ -> fail ("Unknown reflection type universe expression: " ++ show t)
1078+reifyTTUExp t = fail ("Unknown reflection type universe expression: " ++ show t)
1080+-- | Create a reflected call to a named function/constructor
1081+reflCall :: String -> [Raw] -> Raw
1082+reflCall funName args
1083+ = raw_apply (Var (reflm funName)) args
1085+-- | Lift a term into its Language.Reflection.TT representation
1086+reflect :: Term -> Raw
1088+ = reflCall "P" [reflectNameType nt, reflectName n, reflect t]
1090+ = reflCall "V" [RConstant (I n)]
1091+reflect (Bind n b x)
1092+ = reflCall "Bind" [reflectName n, reflectBinder b, reflect x]
1094+ = reflCall "App" [reflect f, reflect x]
1095+reflect (Constant c)
1096+ = reflCall "TConst" [reflectConstant c]
1098+ = reflCall "Proj" [reflect t, RConstant (I i)]
1099+reflect (Erased) = Var (reflm "Erased")
1100+reflect (Impossible) = Var (reflm "Impossible")
1101+reflect (TType exp) = reflCall "TType" [reflectUExp exp]
1103+reflectNameType :: NameType -> Raw
1104+reflectNameType (Bound) = Var (reflm "Bound")
1105+reflectNameType (Ref) = Var (reflm "Ref")
1106+reflectNameType (DCon x y)
1107+ = reflCall "DCon" [RConstant (I x), RConstant (I y)]
1108+reflectNameType (TCon x y)
1109+ = reflCall "TCon" [RConstant (I x), RConstant (I y)]
1111+reflectName :: Name -> Raw
1112+reflectName (UN str)
1113+ = reflCall "UN" [RConstant (Str str)]
1114+reflectName (NS n ns)
1115+ = reflCall "NS" [ reflectName n
1117+ raw_apply ( Var $ NS (UN "::") ["List", "Prelude"] )
1118+ [ RConstant StrType, RConstant (Str n), s ])
1119+ ( raw_apply ( Var $ NS (UN "Nil") ["List", "Prelude"] )
1120+ [ RConstant StrType ])
1123+reflectName (MN i n)
1124+ = reflCall "MN" [RConstant (I i), RConstant (Str n)]
1125+reflectName (NErased) = Var (reflm "NErased")
1127+reflectBinder :: Binder Term -> Raw
1128+reflectBinder (Lam t)
1129+ = reflCall "Lam" [Var (reflm "TT"), reflect t]
1130+reflectBinder (Pi t)
1131+ = reflCall "Pi" [Var (reflm "TT"), reflect t]
1132+reflectBinder (Let x y)
1133+ = reflCall "Let" [Var (reflm "TT"), reflect x, reflect y]
1134+reflectBinder (NLet x y)
1135+ = reflCall "NLet" [Var (reflm "TT"), reflect x, reflect y]
1136+reflectBinder (Hole t)
1137+ = reflCall "Hole" [Var (reflm "TT"), reflect t]
1138+reflectBinder (GHole t)
1139+ = reflCall "GHole" [Var (reflm "TT"), reflect t]
1140+reflectBinder (Guess x y)
1141+ = reflCall "Guess" [Var (reflm "TT"), reflect x, reflect y]
1142+reflectBinder (PVar t)
1143+ = reflCall "PVar" [Var (reflm "TT"), reflect t]
1144+reflectBinder (PVTy t)
1145+ = reflCall "PVTy" [Var (reflm "TT"), reflect t]
1147+reflectConstant :: Const -> Raw
1148+reflectConstant c@(I _) = reflCall "I" [RConstant c]
1149+reflectConstant c@(BI _) = reflCall "BI" [RConstant c]
1150+reflectConstant c@(Fl _) = reflCall "Fl" [RConstant c]
1151+reflectConstant c@(Ch _) = reflCall "Ch" [RConstant c]
1152+reflectConstant c@(Str _) = reflCall "Str" [RConstant c]
1153+reflectConstant (IType) = Var (reflm "IType")
1154+reflectConstant (BIType) = Var (reflm "BIType")
1155+reflectConstant (FlType) = Var (reflm "FlType")
1156+reflectConstant (ChType) = Var (reflm "ChType")
1157+reflectConstant (StrType) = Var (reflm "StrType")
1158+reflectConstant c@(B8 _) = reflCall "B8" [RConstant c]
1159+reflectConstant c@(B16 _) = reflCall "B16" [RConstant c]
1160+reflectConstant c@(B32 _) = reflCall "B32" [RConstant c]
1161+reflectConstant c@(B64 _) = reflCall "B64" [RConstant c]
1162+reflectConstant (B8Type) = Var (reflm "B8Type")
1163+reflectConstant (B16Type) = Var (reflm "B16Type")
1164+reflectConstant (B32Type) = Var (reflm "B32Type")
1165+reflectConstant (B64Type) = Var (reflm "B64Type")
1166+reflectConstant (PtrType) = Var (reflm "PtrType")
1167+reflectConstant (VoidType) = Var (reflm "VoidType")
1168+reflectConstant (Forgot) = Var (reflm "Forgot")
1170+reflectUExp :: UExp -> Raw
1171+reflectUExp (UVar i) = reflCall "UVar" [RConstant (I i)]
1172+reflectUExp (UVal i) = reflCall "UVal" [RConstant (I i)]
1174+-- | Reflect the environment of a proof into a List (TTName, Binder TT)
1175+reflectEnv :: Env -> Raw
1176+reflectEnv = foldr consToEnvList emptyEnvList
1178+ consToEnvList :: (Name, Binder Term) -> Raw -> Raw
1179+ consToEnvList (n, b) l
1180+ = raw_apply (Var (NS (UN "::") ["List", "Prelude"]))
1182+ , raw_apply (Var pairCon) [ (Var $ reflm "TTName")
1183+ , (RApp (Var $ reflm "Binder")
1184+ (Var $ reflm "TT"))
1191+ emptyEnvList :: Raw
1192+ emptyEnvList = raw_apply (Var (NS (UN "Nil") ["List", "Prelude"]))
1197+ = raw_apply (Var pairTy) [ (Var $ reflm "TTName")
1198+ , (RApp (Var $ reflm "Binder") (Var $ reflm "TT"))
819solveAll = try (do solve; solveAll) (return ())
1201solveAll = try (do solve; solveAll) (return ())