caledon 2.0.0.0 → 2.1.0.0
raw patch · 15 files changed
+259/−251 lines, 15 files
Files
- AST.hs +11/−8
- Choice.hs +11/−1
- Context.hs +11/−12
- HOU.hs +114/−93
- Main.hs +8/−7
- Parser.hs +9/−7
- README.md +31/−11
- TopoSortAxioms.hs +1/−1
- caledon.cabal +1/−1
- examples/nondet.ncc +43/−0
- examples/prelude.ncc +19/−20
- media/.DS_Store binary
- media/._.DS_Store binary
- media/logo.png binary
- media/logo.svg +0/−90
AST.hs view
@@ -2,7 +2,8 @@ FlexibleInstances, PatternGuards, BangPatterns,- FlexibleContexts+ FlexibleContexts,+ TupleSections #-} module AST where@@ -38,7 +39,7 @@ type Type = Spine type Term = Spine -data Predicate = Predicate { predIsSound :: !Bool, predName :: !Name, predType :: !Type, predConstructors :: ![(Name,Type)] }+data Predicate = Predicate { predIsSound :: !Bool, predName :: !Name, predType :: !Type, predConstructors :: ![(Bool,(Name,Type))] } | Query { predName :: !Name, predType :: !Spine} | Define { predIsSound :: !Bool, predName :: !Name, predValue :: !Spine, predType :: !Type} deriving (Eq)@@ -103,10 +104,10 @@ showT False = "unsound " instance Show Predicate where- show (Predicate s nm ty []) = showT s ++ nm ++ " : " ++ show ty ++ ";"+ show (Predicate s nm ty []) = showT s ++ nm ++ " : " ++ show ty show (Predicate s nm ty (a:cons)) =- showT s++ nm ++ " : " ++ show ty ++ "\n" ++ " | " ++ showSingle a ++ concatMap (\x-> "\n | " ++ showSingle x) cons ++ ";"- where showSingle (nm,ty) = nm ++ " = " ++ show ty+ showT s++ nm ++ " : " ++ show ty++showSingle a ++ concatMap (\x-> showSingle x) cons+ where showSingle (b,(nm,ty)) = (if b then "\n >| " else " | ") ++nm ++ " = " ++ show ty show (Query nm val) = "query " ++ nm ++ " = " ++ show val show (Define s nm val ty) = showT s ++ nm ++ " : " ++ show ty ++"\n as "++show val @@ -237,7 +238,7 @@ instance Subst Predicate where- substFree sub f (Predicate s nm ty cons) = Predicate s nm (substFree sub f ty) ((\(nm,t) -> (nm,substFree sub f t)) <$> cons)+ substFree sub f (Predicate s nm ty cons) = Predicate s nm (substFree sub f ty) ((\(b,(nm,t)) -> (b,(nm,substFree sub f t))) <$> cons) substFree sub f (Query nm ty) = Query nm (substFree sub f ty) substFree sub f (Define s nm val ty) = Define s nm (substFree sub f val) (substFree sub f ty) @@ -383,7 +384,7 @@ regenWithMem cons = case cons of a :=: b -> regenM (:=:) a b a :@: b -> regenM (:@:) a b - + instance RegenAbsVars Constraint where regenAbsVars cons = case cons of Bind q nm ty cons -> do@@ -451,6 +452,8 @@ ] +anonymous ty = ((False,100),ty)+ envSet = S.fromList $ map fst consts toNCCchar c = Spine ['\'',c,'\''] []@@ -459,7 +462,7 @@ nil = Spine "nil" [tycon "a" char] cons a l = Spine "cons" [tycon "a" char, a,l] -envConsts = M.fromList consts+envConsts = anonymous <$> M.fromList consts isChar ['\'',_,'\''] = True isChar _ = False
Choice.hs view
@@ -12,7 +12,7 @@ import Data.Functor import Control.Applicative import Control.Monad.Error.Class (catchError, throwError, MonadError)-+import Control.Monad.Cont data Choice a = Choice a :<|>: Choice a | Fail String@@ -69,3 +69,13 @@ catchError try1 foo_try2 = case runError try1 of Left s -> foo_try2 s Right a -> Success a++type CONT_T a m c = ((c -> m a) -> m a)++-- why doesn't this exist in the standard library?+instance (Monad m, Alternative m) => Alternative (ContT a m) where+ empty = lift $ empty+ c1 <|> c2 = ContT $ \cont -> m1f cont <|> m2f cont+ where m1f = runContT c1+ m2f = runContT c2+
Context.hs view
@@ -21,8 +21,10 @@ -------------------- --- context map --- ---------------------type ContextMap = Map Name Type+type ContextMap = Map Name ((Bool,Integer),Type)+type ContextMapT = Map Name Type + -------------------------------- --- constraint context list --- --------------------------------@@ -194,12 +196,12 @@ getForalls :: Env ContextMap getForalls = do ctx <- ctxtMap <$> stateCtxt <$> get- return $ elmType <$> M.filter (\q -> elmQuant q == Forall) ctx+ return $ anonymous <$> elmType <$> M.filter (\q -> elmQuant q == Forall) ctx getExists :: Env ContextMap getExists = do ctx <- ctxtMap <$> stateCtxt <$> get- return $ elmType <$> M.filter (\q -> elmQuant q == Exists) ctx+ return $ anonymous <$> elmType <$> M.filter (\q -> elmQuant q == Exists) ctx getConstants :: Env ContextMap getConstants = ask @@ -214,14 +216,15 @@ getFullCtxt = do constants <- getConstants ctx <- ctxtMap <$> stateCtxt <$> get- return $ M.union (elmType <$> ctx) constants+ return $ M.union (anonymous <$> elmType <$> ctx) constants getVariablesBeforeExists :: Name -> Env ContextMap getVariablesBeforeExists nm = do constants <- getConstants ctx <- stateCtxt <$> get let bind = ctxtMap ctx M.! nm- return $ M.union constants $ M.fromList $ snd <$> getBefore "IN: getVariablesBeforeExists" bind ctx+ return $ M.union constants + $ M.fromList $ (\(nm,v) -> (nm, anonymous v)) <$> snd <$> getBefore "IN: getVariablesBeforeExists" bind ctx modifyCtxt :: (Context -> Context) -> Env ()@@ -232,7 +235,7 @@ --- traversal monads --- ------------------------- lookupConstant :: Name -> Env (Maybe Type)-lookupConstant x = (M.lookup x) <$> ask +lookupConstant x = fmap snd <$> (M.lookup x) <$> ask type TypeChecker = ContT Spine Env @@ -240,11 +243,7 @@ typeCheckToEnv m = listen $ runContT m return -addToEnv :: (Name -> Spine -> Constraint -> Constraint) -> Name -> Spine -> TypeChecker a -> TypeChecker a-addToEnv e x ty = mapContT (censor $ e x ty) . liftLocal ask local (M.insert x ty) --------------------------- Universe Monad -------------------------- - +addToEnv :: (Name -> Type -> Constraint -> Constraint) -> Name -> Type -> TypeChecker a -> TypeChecker a+addToEnv e x ty = mapContT (censor $ e x ty) . liftLocal ask local (M.insert x $ anonymous ty)
HOU.hs view
@@ -13,7 +13,7 @@ import Control.Monad.State (StateT, forM_,runStateT, modify, get) import Control.Monad.RWS (RWST, runRWST, ask, tell) import Control.Monad.Error (throwError, MonadError)-import Control.Monad (unless, forM, replicateM, void)+import Control.Monad (unless, forM, replicateM, void, (<=<)) import Control.Monad.Trans (lift) import Control.Applicative import qualified Data.Foldable as F@@ -56,35 +56,29 @@ return $ l1 ++ l2 flatten (SCons l) = return l +type UnifyResult = Maybe (Substitution, [SCons])+ unify :: Constraint -> Env Substitution unify cons = do cons <- vtrace 5 ("CONSTRAINTS1: "++show cons) $ regenAbsVars cons cons <- vtrace 5 ("CONSTRAINTS2: "++show cons) $ flatten cons let uniWhile :: Substitution -> [SCons] -> Env (Substitution, [SCons])- uniWhile !sub !c' = do+ uniWhile !sub !c' = fail "" <|> do exists <- getExists c <- regenAbsVars c' - let -- eventually we can make the entire algorithm a graph modification algorithm for speed, - -- such that we don't have to topologically sort every time. Currently this only takes us from O(n log n) to O(n) per itteration, it is- -- not necessarily worth it.- uniWith !wth !backup = do- let searchIn [] r = return Nothing- searchIn (next:l) r = do- c1' <- wth next - case c1' of- Just (sub',next') -> return $ Just (sub', (subst sub' $ reverse r)++- next'- ++subst sub' l)- Nothing -> searchIn l (next:r)- res <- searchIn c []- case res of- Nothing -> do- backup- Just (!sub', c') -> do- let !sub'' = sub *** sub'- modifyCtxt $ subst sub'- uniWhile sub'' $! c'-+ let uniWith !wth !backup = searchIn c []+ where searchIn [] r = finish Nothing+ searchIn (next:l) r = + wth next $ \c1' -> case c1' of+ Just (sub',next') -> finish $ Just (sub', subst sub' (reverse r)++next'++subst sub' l)+ Nothing -> searchIn l $ next:r+ finish Nothing = backup+ finish (Just (!sub', c')) = do+ let !sub'' = sub *** sub'+ modifyCtxt $ subst sub'+ uniWhile sub'' $! c'+ + vtrace 3 ("CONST: "++show c) ( uniWith unifyOne $ uniWith unifySearch@@ -95,32 +89,30 @@ fst <$> uniWhile mempty cons - checkFinished [] = return () checkFinished cval = throwTrace 0 $ "ambiguous constraint: " ++show cval -unifySearch :: SCons -> Env (Maybe (Substitution, [SCons]))-unifySearch (a :@: b) | b /= atom = do- cons <- rightSearch a b- return $ case cons of- Nothing -> Nothing- Just cons -> Just (mempty, cons)-unifySearch _ = return Nothing+unifySearch :: SCons -> CONT_T b Env UnifyResult+unifySearch (a :@: b) return | b /= atom = rightSearch a b $ newReturn return+unifySearch _ return = return Nothing -unifySearchAtom (a :@: b) = do- cons <- rightSearch a b- return $ case cons of- Nothing -> Nothing- Just cons -> Just (mempty, cons)-unifySearchAtom _ = return Nothing+newReturn return cons = return $ case cons of+ Nothing -> Nothing+ Just cons -> Just (mempty, cons) -unifyOne :: SCons -> Env (Maybe (Substitution , [SCons]))-unifyOne (a :=: b) = do+unifySearchAtom :: SCons -> CONT_T b Env UnifyResult+unifySearchAtom (a :@: b) return = rightSearch a b $ newReturn return+unifySearchAtom _ return = return Nothing++++unifyOne :: SCons -> CONT_T b Env UnifyResult+unifyOne (a :=: b) return = do c' <- isolateForFail $ unifyEq $ a :=: b case c' of - Nothing -> isolateForFail $ unifyEq $ b :=: a+ Nothing -> return =<< (isolateForFail $ unifyEq $ b :=: a) r -> return r-unifyOne _ = return Nothing+unifyOne _ return = return Nothing unifyEq cons@(a :=: b) = case (a,b) of (Spine "#imp_forall#" [ty, l], b) -> vtrace 1 "-implicit-" $ do@@ -164,7 +156,7 @@ raiseToTop bind (Spine x yl) $ \(a@(Spine x yl),ty) sub -> case subst sub s' of b@(Spine x' y'l) -> vtrace 4 "-gs-" $ do- bind' <- getElm ("gvar-blah: "++show cons) x'+ bind' <- getElm ("gvar-blah: "++show cons) x' case bind' of Right ty' -> vtraceShow 1 2 "-gc-" cons $ -- gvar-const --if allElementsAreVariables yl@@ -396,7 +388,8 @@ -- need bidirectional search!-rightSearch m goal = vtrace 1 ("-rs- "++show m++" ∈ "++show goal) $ +rightSearch :: Term -> Type -> CONT_T b Env (Maybe [SCons])+rightSearch m goal ret = vtrace 1 ("-rs- "++show m++" ∈ "++show goal) $ fail (show m++" ∈ "++show goal) <|> case goal of Spine "#forall#" [a, b] -> do y <- getNewWith "@sY"@@ -404,7 +397,7 @@ let b' = b `apply` var x' modifyCtxt $ addToTail "-rsFf-" Forall x' a modifyCtxt $ addToTail "-rsFe-" Exists y b'- return $ Just [ var y :=: m `apply` var x' , var y :@: b']+ ret $ Just [ var y :=: m `apply` var x' , var y :@: b'] Spine "#imp_forall#" [_, Abs x a b] -> do y <- getNewWith "@isY"@@ -412,26 +405,30 @@ let b' = subst (x |-> var x') b modifyCtxt $ addToTail "-rsIf-" Forall x' a modifyCtxt $ addToTail "-rsIe-" Exists y b'- return $ Just [ var y :=: m `apply` (tycon x $ var x')- , var y :@: b'- ]- Spine "putChar" [c@(Spine ['\'',l,'\''] [])] ->- case unsafePerformIO $ putStr $ l:[] of- () -> return $ Just [ m :=: Spine "putCharImp" [c]]- Spine "putChar" [_] -> vtrace 0 "FAILING PUTCHAR" $ return Nothing+ ret $ Just [ var y :=: m `apply` (tycon x $ var x')+ , var y :@: b'+ ]+ Spine "putChar" [c@(Spine ['\'',l,'\''] [])] -> ret $ Just $ (m :=: Spine "putCharImp" [c]):seq action []+ where action = unsafePerformIO $ putStr $ l:[]++ Spine "putChar" [_] -> vtrace 0 "FAILING PUTCHAR" $ ret Nothing Spine "readLine" [l] -> case toNCCstring $ unsafePerformIO $ getLine of- !s -> do+ s -> do -- ensure this is lazy so we don't check for equality unless we have to. y <- getNewWith "@isY" let ls = l `apply` s modifyCtxt $ addToTail "-rl-" Exists y ls- return $ Just [m :=: Spine "readLineImp" [l,s, var y], var y :@: Spine "run" [ls]]+ ret $ Just [m :=: Spine "readLineImp" [l,s {- this is only safe because lists are lazy -}, var y], var y :@: Spine "run" [ls]] _ | goal == kind -> do case m of Abs{} -> throwError "not properly typed"- _ | m == tipe || m == atom -> return $ Just []- _ -> F.asum $ return . Just . return . (m :=:) <$> [atom , tipe]+ _ | m == tipe || m == atom -> ret $ Just []+ _ -> breadth -- we should pretty much always use breadth first search here maybe, since this is type search+ where srch r1 r2 = r1 $ F.asum $ r2 . Just . return . (m :=:) <$> [atom , tipe] -- for breadth first+ breadth = srch (ret =<<) return+ depth = srch id (appendErr "" . ret)+ Spine nm _ -> do constants <- getConstants foralls <- getForalls@@ -440,7 +437,7 @@ isFixed a = isChar a || M.member a env - getFixedType a | isChar a = Just $ var "char"+ getFixedType a | isChar a = Just $ anonymous $ var "char" getFixedType a = M.lookup a env let mfam = case m of @@ -448,10 +445,10 @@ Spine nm _ -> case getFixedType nm of Just t -> Just (nm,t) Nothing -> Nothing- - sameFamily (_, Abs _ _ _) = False- sameFamily ("pack",s) = "#exists#" == nm- sameFamily (_,s) = getFamily s == nm++ sameFamily (_, (_,Abs{})) = False+ sameFamily ("pack",_) = "#exists#" == nm+ sameFamily (_,(_,s)) = getFamily s == nm targets <- case mfam of Just (nm,t) -> return $ [(nm,t)]@@ -459,25 +456,36 @@ let excludes = S.toList $ S.intersection (M.keysSet exists) $ freeVariables m searchMaps <- mapM getVariablesBeforeExists excludes - let searchMap = M.union env $ case searchMaps of+ let searchMap :: ContextMap+ searchMap = M.union env $ case searchMaps of [] -> mempty a:l -> foldr (M.intersection) a l return $ filter sameFamily $ M.toList searchMap if all isFixed $ S.toList $ S.union (freeVariables m) (freeVariables goal)- then return $ Just []+ then ret $ Just [] else case targets of- [] -> return Nothing- _ -> Just <$> (F.asum $ leftSearch m goal <$> reverse targets) -- reversing works for now, but not forever! need a heuristics + bidirectional search + control structures-+ [] -> ret Nothing+ _ -> inter [] $ sortBy (\a b -> compare (getVal a) (getVal b)) targets+ where ls (nm,target) = leftSearch (m,goal) (var nm, target)+ getVal = snd . fst . snd+ + inter [] [] = throwError "no more options"+ inter cg [] = appendErr "" $ F.asum $ reverse cg+ inter cg ((nm,((sequ,_),targ)):l) = do+ res <- Just <$> ls (nm,targ)+ if sequ + then (if not $ null cg then (appendErr "" (F.asum $ reverse cg) <|>) else id) $ + (appendErr "" $ ret res) <|> inter [] l+ else inter (ret res:cg) l+ + a .-. s = foldr (\k v -> M.delete k v) a s -leftSearch m goal (x,target) = vtrace 1 ("LS: " ++ show m ++" ∈ "++ show goal- ++"\n\t@ " ++x++" : " ++show target)- $ leftCont (var x) target- where leftCont n target = throwTrace 3 ("DEFER: LS: " ++ show m ++" ∈ "++ show goal- ++"\n\t@ " ++x++" : " ++show target) <|> case target of+leftSearch (m,goal) (x,target) = vtrace 1 ("LS: " ++ show x++" ∈ " ++show target++" >> " ++show m ++" ∈ "++ show goal)+ $ leftCont x target+ where leftCont n target = case target of Spine "#forall#" [a, b] -> do x' <- getNewWith "@sla" modifyCtxt $ addToTail "-lsF-" Exists x' a@@ -490,9 +498,10 @@ cons <- leftCont (n `apply` (tycon x $ var x')) (subst (x |-> var x') b) return $ cons++[var x' :@: a] Spine _ _ -> do- return $ [goal :=: target , m :=: n]+ return $ [goal :=: target, m :=: n] _ -> error $ "λ does not have type atom: " ++ show target + search :: Type -> Env (Substitution, Term) search ty = do e <- getNewWith "@e"@@ -626,7 +635,7 @@ Nothing -> lift $ throwTrace 0 $ "variable: "++show head++" not found in the environment." ++ "\n\t from "++ show sp ++ "\n\t from "++ show ty- Just ty' -> Spine head <$> chop ty' args+ Just ty' -> Spine head <$> chop (snd ty') args checkFullType :: Spine -> Type -> Env (Spine, Constraint) checkFullType val ty = typeCheckToEnv $ checkType val ty@@ -634,8 +643,8 @@ ---------------------- --- type inference --- -----------------------typeInfer :: ContextMap -> (Name,Spine,Type) -> Choice (Term,Type, ContextMap)-typeInfer env (nm,val,ty) = (\r -> (\(a,_,_) -> a) <$> runRWST r (M.union envConsts env) emptyState) $ do+typeInfer :: ContextMap -> ((Bool,Integer),Name,Spine,Type) -> Choice (Term,Type, ContextMap)+typeInfer env (seqi,nm,val,ty) = (\r -> (\(a,_,_) -> a) <$> runRWST r (M.union envConsts env) emptyState) $ do ty <- return $ alphaConvert mempty ty val <- return $ alphaConvert mempty val @@ -651,7 +660,7 @@ resT = rebuildFromMem mem' $ unsafeSubst sub ty vtrace 0 ("RESULT: "++nm++" : "++show resV) $- return $ (resV,resT, M.insert nm resV env)+ return $ (resV,resT, M.insert nm (seqi,resV) env) unsafeSubst s (Spine nm apps) = let apps' = unsafeSubst s <$> apps in case s ! nm of Just nm -> rebuildSpine nm apps'@@ -661,39 +670,43 @@ ---------------------------- --- the public interface --- -----------------------------typeCheckAxioms :: [(Maybe Name,Bool,Name,Term,Type)] -> Choice ContextMap++type FlatPred = [(Maybe Name,(Bool,Integer,Bool),Name,Term,Type)]+typeCheckAxioms :: FlatPred -> Choice Substitution typeCheckAxioms lst = do -- check the closedness of families. this gets done -- after typechecking since family checking needs to evaluate a little bit -- in order to allow defs in patterns- let notval (_,s,'#':'v':':':_,_,_) = False- notval (_,s,_,_,_) = True + let notval (_,_,'#':'v':':':_,_,_) = False+ notval (_,_,_,_,_) = True - unsound (_,s,_,_,_) = not s+ unsound (_,(_,_,s),_,_,_) = not s - tys = M.fromList $ map (\(_,_,nm,ty,_) -> (nm,ty)) $ filter notval lst+ tys = M.fromList $ map (\(_,(b,i,_),nm,ty,_) -> (nm,((b,i),ty))) $ filter notval lst uns = S.fromList $ map (\(_,_,nm,ty,_) -> nm) $ filter unsound $ filter notval lst + inferAll :: (ContextMap, FlatPred, FlatPred) -> Choice (FlatPred,ContextMap) inferAll (l , r, []) = return (r,l) inferAll (_ , r, (_,_,nm,_,_):_) | nm == tipeName = throwTrace 0 $ tipeName++" can not be overloaded" inferAll (_ , r, (_,_,nm,_,_):_) | nm == atomName = throwTrace 0 $ atomName++" can not be overloaded"- inferAll (l , r, (fam,s,nm,val,ty):toplst) = do+ inferAll (l , r, (fam,(b,i,s),nm,val,ty):toplst) = do (val,ty,l') <- appendErr ("can not infer type for: "++nm++" : "++show val) $ trace ("Checking: " ++nm) $ vtrace 0 ("\tVAL: " ++show val ++"\n\t:: " ++show ty) $- typeInfer l (nm, val,ty) -- constrain the breadth first search to be local!+ typeInfer l ((b,i),nm, val,ty) -- constrain the breadth first search to be local! -- do the family check after ascription removal and typechecking because it can involve computation! unless (fam == Nothing || Just (getFamily val) == fam) $ throwTrace 0 $ "not the right family: need "++show fam++" for "++nm ++ " = " ++show val inferAll $ case nm of- '#':'v':':':nm' -> (sub <$> l', (fam,s,nm,val,ty):r , fsub <$> toplst) - where sub = subst $ nm' |-> ascribe val ty -- the ascription isn't necessary because we don't have unbound variables+ '#':'v':':':nm' -> (sub' <$> l', (fam,(b,i,s),nm,val,ty):r , fsub <$> toplst) + where sub' (b,a)= (b, sub a)+ sub = subst $ nm' |-> ascribe val ty -- the ascription isn't necessary because we don't have unbound variables fsub (fam,s,nm,val,ty) = (fam,s,nm, sub val, sub ty)- _ -> (l', (fam,s,nm,val,ty):r, toplst)+ _ -> (l', (fam,(b,i,s),nm,val,ty):r, toplst) (lst',l) <- inferAll (tys, [], topoSortAxioms lst) @@ -711,22 +724,30 @@ doubleCheckAll (S.union envSet uns) $ topoSortAxioms lst' - return l + return $ snd <$> l typeCheckAll :: [Predicate] -> Choice [Predicate] typeCheckAll preds = do- let toAxioms (Predicate s nm ty cs) = (Just $ atomName,s,nm,ty,tipe):map (\(nm',ty') -> (Just nm,False, nm',ty',atom)) cs- toAxioms (Query nm val) = [(Nothing, False,nm,val,atom)]- toAxioms (Define s nm val ty) = [(Nothing,False, nm,ty,kind), (Nothing,s, "#v:"++nm,val,ty)]- tyMap <- typeCheckAxioms $ concatMap toAxioms preds++ tyMap <- typeCheckAxioms $ toAxioms True preds - let newPreds (Predicate t nm _ cs) = Predicate t nm (tyMap M.! nm) $ map (\(nm,_) -> (nm,tyMap M.! nm)) cs+ let newPreds (Predicate t nm _ cs) = Predicate t nm (tyMap M.! nm) $ map (\(b,(nm,_)) -> (b,(nm, tyMap M.! nm))) cs newPreds (Query nm _) = Query nm (tyMap M.! nm) newPreds (Define t nm _ _) = Define t nm (tyMap M.! ("#v:"++nm)) (tyMap M.! nm) return $ newPreds <$> preds++toAxioms :: Bool -> [Predicate] -> [(Maybe [Char], (Bool, Integer, Bool), Name, Type, Spine)] +toAxioms b = concat . zipWith toAxioms' [0..]+ where toAxioms' j (Predicate s nm ty cs) = (Just $ atomName,(False,j,s),nm,ty,tipe):zipWith (\(sequ,(nm',ty')) i -> (Just nm,(sequ,i,False), nm',ty',atom)) cs [0..]+ toAxioms' j (Query nm val) = [(Nothing, (False,j,False),nm,val,atom)]+ toAxioms' j (Define s nm val ty) = (if b then ((Nothing,(False,j,s), "#v:"++nm,val,ty):) else id)+ [(Nothing,(False,j,False), nm,ty,kind)] -solver :: [(Name,Type)] -> Type -> Either String [(Name, Term)]-solver axioms tp = case runError $ runRWST (search tp) (M.union envConsts $ M.fromList axioms) emptyState of+toSimpleAxioms :: [Predicate] -> ContextMap+toSimpleAxioms l = M.fromList $ (\(_,(seqi,i,_),nm,t,_) -> (nm,((seqi,i),t))) <$> toAxioms False l++solver :: ContextMap -> Type -> Either String [(Name, Term)]+solver axioms tp = case runError $ runRWST (search tp) (M.union envConsts axioms) emptyState of Right ((_,tm),_,_) -> Right $ [("query", tm)] Left s -> Left $ "reification not possible: "++s
Main.hs view
@@ -39,15 +39,16 @@ putStrLn "\nTARGETS: " forM_ targets $ \s -> putStrLn $ show s++"\n" - let allTypes c = (predName c, predType c):predConstructors c- predicates' = sub predicates+ let predicates' = sub predicates targets' = sub targets- forM_ targets' $ \target ->- case solver (concatMap allTypes predicates') $ predType target of+ + axioms = toSimpleAxioms predicates'+ + forM_ targets' $ \target -> do+ putStrLn $ "\nTARGET: \n"++show target+ case solver axioms $ predType target of Left e -> putStrLn $ "ERROR: "++e- Right sub -> putStrLn $- "\nTARGET: \n"++show target- ++"\n\nSOLVED WITH:\n"+ Right sub -> putStrLn $ "SOLVED WITH:\n" ++concatMap (\(a,b) -> a++" => "++show b++"\n") sub main = do
Parser.hs view
@@ -115,15 +115,17 @@ unsound = do reserved "unsound" - vsn False - + vsn False+ + + vsn s = do (nm,ty) <- named decTipe- let more = do reservedOp "|"-- lst <- flip sepBy1 (reservedOp "|") $ do- (nm,t) <- named decPred- return (nm,t)+ let more = do lst <- many1 $ do+ seqi <- (reservedOp "|" >> return False) + <|> (reservedOp ">|" >> return True)+ (nm,t) <- named decPred+ return (seqi,(nm,t)) optional semi return $ Predicate s nm ty lst
README.md view
@@ -81,11 +81,13 @@ | succ = num -> num defn add : num -> num -> num -> prop- | add_zero = {N} add zero N N- | add_succ = {N}{M}{R} add (succ N) M (succ R) <- add N M R+ | add_zero = [N] add zero N N+ | add_succ = [N M R] add (succ N) M (succ R) <- add N M R -- we can define subtraction from addition!-query subtract = add (succ (succ zero)) 'v (succ (succ (succ zero)))+defn subtract : num -> num -> num -> prop+ as \a b c : num . add b c a+ ``` * Some basic IO: Using unix pipes, this Caledon can be used more seriously. Somebody plz write a wrapper?@@ -98,14 +100,6 @@ , putStr "\nbye!\n") ``` -* Shell commands: --```-defn ls : string -> string -> prop- | ls-imp = [Args Out : string] - ls Args S <- cmd "ls" Args Out-```- * Higher order logic programming: like in twelf and lambda-prolog. This makes HOAS much easier to do. ```@@ -182,6 +176,32 @@ -- this syntax is rather verbose for the moment. I have yet to add typeclass syntax sugar. ```++* Nondeterminism control: You can now control what patterns to match against sequentially versus in concurrently. This gives you massive control over program execution, and in the future might be implemented with REAL threads!++```+defn runBoth : bool -> prop+ >| run0 = [A] runBoth A + <- putStr "tttt "+ <- A =:= true++ | run1 = [A] runBoth A+ <- putStr "vvvv"+ <- A =:= true++ | run2 = [A] runBoth A+ <- putStr "qqqq"+ <- A =:= true++ >| run3 = [A] runBoth A+ <- putStr " jjjj"+ <- A =:= false++query main = runBoth false++-- main should print out something along the lines of "tttt vvqvqvqq jjjj"+```+ * Arbitrary operator fixities: combined with the calculus of constructions, you can nearly do agda style syntax (with a bit of creativity)!
TopoSortAxioms.hs view
@@ -9,7 +9,7 @@ $ filter (not . flip elem (map fst consts)) $ S.toList $ freeVariables val `S.union` freeVariables ty -topoSortAxioms :: [(Maybe Name, Bool, Name,Term,Type)] -> [(Maybe Name, Bool, Name,Term,Type)]+topoSortAxioms :: [(Maybe Name, (Bool,Integer,Bool), Name,Term,Type)] -> [(Maybe Name, (Bool,Integer,Bool), Name,Term,Type)] topoSortAxioms axioms = map ((\((fam,s,val,ty),n,_) -> (fam,s,n,val,ty)) . v2nkel) vlst where (graph, v2nkel, _) = graphFromEdges $ map (\(fam,s,nm,val,ty) -> ((fam,s,val,ty), nm , getVars val ty)) axioms
caledon.cabal view
@@ -1,6 +1,6 @@ Name: caledon -Version: 2.0.0.0+Version: 2.1.0.0 Description: a dependently typed, polymorphic, higher order logic programming language based on the calculus of constructions designed for easier metaprogramming capabilities.
+ examples/nondet.ncc view
@@ -0,0 +1,43 @@+defn char : prop -- builtin+defn putChar : char -> prop -- builtin+ | putCharImp = [A] putChar A++defn bool : prop+ | true = bool+ | false = bool++fixity none 1 =:=+defn =:= : {Q} Q -> Q -> prop+ | eq = [a : prop][b:a] (=:=) {Q = a} b b++defn runBoth : bool -> prop+ >| run0 = [A] runBoth A + <- putChar 't'+ <- putChar 't'+ <- putChar 't'+ <- putChar 't'+ <- A =:= true++ | run1 = [A] runBoth A+ <- putChar 'v'+ <- putChar 'v'+ <- putChar 'v'+ <- putChar 'v'+ <- A =:= true++ | run2 = [A] runBoth A+ <- putChar 'q'+ <- putChar 'q'+ <- putChar 'q'+ <- putChar 'q'+ <- A =:= true++ >| run3 = [A] runBoth A+ <- putChar 'j'+ <- putChar 'j'+ <- putChar 'j'+ <- putChar 'j'+ <- A =:= false+ +query main = runBoth false+
examples/prelude.ncc view
@@ -12,10 +12,9 @@ | do = io | , = io -> prop -> io - defn run : io -> prop- | runDo = run do- | runSeq = [A][B] run (A , B) <- run A + >| runDo = run do+ >| runSeq = [A][B] run (A , B) <- run A <- B defn readLine : (string -> io) -> prop -- builtin @@ -62,12 +61,12 @@ ------------------- fixity none 1 =:= defn =:= : {Q} Q -> Q -> prop- | eq = [a : prop][b:a] (=:=) {Q = a} b b+ >| eq = [a : prop][b:a] (=:=) {Q = a} b b -- searching for these is SLOW fixity none 0 /\ defn /\ : prop -> prop -> prop- | and = [a b : prop] a -> b -> a /\ b+ >| and = [a b : prop] a -> b -> a /\ b fixity none 0 \/ defn \/ : prop -> prop -> prop@@ -91,7 +90,7 @@ -- it correctly infers 169, and M (but it eta expands Foo when it infers it) !! fixity right 3 ++ defn ++ : {M}{Foo}{cm : concatable M Foo} M -> M -> M -> prop- | ppimp = [M][Foo : M -> M -> M -> prop][M1 M2 M3 : M] + >| ppimp = [M][Foo : M -> M -> M -> prop][M1 M2 M3 : M] (++) {Foo = Foo} M1 M2 M3 <- concatable M Foo <- Foo M1 M2 M3 @@ -100,11 +99,11 @@ --- Order --- ------------- defn orderable : [M : prop] (M -> M -> prop) -> prop- | orderableNatural = orderable natural lte-nat+ >| orderableNatural = orderable natural lte-nat fixity right 3 =< defn =< : {M : prop}{Foo: M -> M -> prop}{co : orderable M Foo} M -> M -> prop- | ooimp = [M][Foo : M -> M -> prop] [M1 M2 : M] + >| ooimp = [M][Foo : M -> M -> prop] [M1 M2 : M] (=<) {M = M} M1 M2 <- orderable M Foo <- Foo M1 M2@@ -119,8 +118,8 @@ query findSat0 = free A : natural . A =:= zero defn add : natural -> natural -> natural -> prop- | add_z = [N] add zero N N- | add_s = [N M R] add N M R -> add (succ N) M (succ R)+ >| add_z = [N] add zero N N+ >| add_s = [N M R] add N M R -> add (succ N) M (succ R) query add0 = add (succ zero) zero (succ zero) @@ -132,13 +131,13 @@ defn lte-nat : natural -> natural -> prop- | leqZero = [B] lte-nat zero B- | leqSucc = [A B] lte-nat (succ A) (succ B) <- lte-nat A B+ >| leqZero = [B] lte-nat zero B+ >| leqSucc = [A B] lte-nat (succ A) (succ B) <- lte-nat A B fixity none 3 < defn < : natural -> natural -> prop- | ltZero = [B] zero < succ B- | ltSucc = [A B] succ A < succ B <- A < B+ >| ltZero = [B] zero < succ B+ >| ltSucc = [A B] succ A < succ B <- A < B query add2 = exists A : natural . add (succ zero) zero A @@ -164,16 +163,16 @@ | cons = {a} a -> list a -> list a defn concatList : {A} list A -> list A -> list A -> prop- | concatListNil = [T][L:list T] concatList {A = T} nil L L- | concatListCons = [T][A B C : list T][V:T] concatList (cons V A) B (cons V C) <- concatList A B C+ >| concatListNil = [T][L:list T] concatList {A = T} nil L L+ >| concatListCons = [T][A B C : list T][V:T] concatList (cons V A) B (cons V C) <- concatList A B C ---------------- --- printing --- ---------------- defn putStr : string -> prop- | putStr_Nil = putStr $ nil {a = char}- | putStr_Cons = [v:char][l: string] + >| putStr_Nil = putStr $ nil {a = char}+ >| putStr_Cons = [v:char][l: string] putStr $ cons {a = char} v l <- putChar v <- putStr l@@ -195,8 +194,8 @@ fixity none 0 ==> defn ==> : {A : prop} bool -> ((A -> A -> A) -> A) -> A -> prop- | thentrue = [a : prop][f: _ -> a] (true ==> f) (f (\a1 a2 : a . a1))- | thenfalse = [b : prop][f: _ -> b] (false ==> f) (f (\a1 a2 : b . a2))+ >| thentrue = [a : prop][f: _ -> a] (true ==> f) (f (\a1 a2 : a . a1))+ >| thenfalse = [b : prop][f: _ -> b] (false ==> f) (f (\a1 a2 : b . a2)) defn not : bool -> bool -> prop as \zq . if zq ==> false |:| true
− media/.DS_Store
binary file changed (6148 → absent bytes)
− media/._.DS_Store
binary file changed (82 → absent bytes)
− media/logo.png
binary file changed (5107 → absent bytes)
− media/logo.svg
@@ -1,90 +0,0 @@-<?xml version="1.0" encoding="UTF-8" standalone="no"?>-<!-- Created with Inkscape (http://www.inkscape.org/) -->--<svg- xmlns:dc="http://purl.org/dc/elements/1.1/"- xmlns:cc="http://creativecommons.org/ns#"- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"- xmlns:svg="http://www.w3.org/2000/svg"- xmlns="http://www.w3.org/2000/svg"- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"- width="64px"- height="64px"- id="svg2985"- version="1.1"- inkscape:version="0.48.2 r9819"- sodipodi:docname="drawing.svg"- inkscape:export-filename="/Users/matt/projects/caledon/logo.png"- inkscape:export-xdpi="332.57077"- inkscape:export-ydpi="332.57077">- <defs- id="defs2987" />- <sodipodi:namedview- id="base"- pagecolor="#ffffff"- bordercolor="#666666"- borderopacity="1.0"- inkscape:pageopacity="0.0"- inkscape:pageshadow="2"- inkscape:zoom="22.378814"- inkscape:cx="28.592229"- inkscape:cy="27.598954"- inkscape:current-layer="layer1"- showgrid="true"- inkscape:document-units="px"- inkscape:grid-bbox="true"- inkscape:window-width="1523"- inkscape:window-height="1193"- inkscape:window-x="788"- inkscape:window-y="93"- inkscape:window-maximized="0" />- <metadata- id="metadata2990">- <rdf:RDF>- <cc:Work- rdf:about="">- <dc:format>image/svg+xml</dc:format>- <dc:type- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />- <dc:title></dc:title>- </cc:Work>- </rdf:RDF>- </metadata>- <g- id="layer1"- inkscape:label="Bird"- inkscape:groupmode="layer"- style="display:inline">- <path- style="fill:#000000;fill-opacity:1;stroke:none"- d="m 18.882872,40.622514 c -1.882884,0.373654 -6.450071,9.787095 -7.791963,9.741122 -1.1680346,-0.04002 -3.7909684,-1.403639 -3.2727272,-2 1.3120082,-1.509782 7.8598822,-9.136821 9.8181822,-9.636363 -1.933103,1.207068 -7.205249,4.964178 -7.257339,4.112511 -0.03501,-0.57236 6.65605,-5.997644 8.893702,-7.567057 0.435723,-0.595323 0.06006,-1.659204 0.508523,-2.522314 1.078658,-2.075958 6.244498,-7.049902 11.619378,-9.209575 3.937841,-1.582259 4.653035,-0.511028 7.668737,-1.779652 0.757625,-0.318712 0.763785,-2.008075 0.02154,-2.160275 -2.700878,-0.553826 -4.390193,-0.702891 -6.611684,-1.976858 2.313795,-0.105189 4.380405,0.04745 5.893645,0.283499 -2.171461,-1.193482 -3.406608,-1.04635 -5.93833,-1.255741 -0.342151,-0.745613 5.728812,-1.158736 6.92448,-0.89678 1.374408,-1.748876 2.506529,-1.943285 4.21727,-1.815105 2.409291,0.180521 3.425495,1.468441 4.45141,5.372928 0.992305,3.776574 -0.06537,12.931591 -7.300427,18.32351 -2.8304,2.109352 -8.844305,3.097519 -10.340542,3.242974 -0.487885,0.04743 -0.231151,0.46574 -1.015401,1.149959 -0.575888,0.502434 6.519236,9.013849 6.519236,9.013849 l -1.163293,0.04776 c 0,0 -6.398156,-8.119769 -6.784269,-8.554688 -0.960981,-1.082449 -0.370467,-1.321021 -2.379025,-1.266572 -0.759544,0.02059 -1.624673,0.770728 -1.365175,1.553149 0.442101,1.33299 3.647077,8.449929 3.647077,8.449929 l -1.029238,0 c 0,0 -2.404917,-5.42565 -3.669892,-7.4839 -0.460686,-0.749586 -0.85396,-1.055399 -0.763051,-1.782672 0.181818,-1.454545 -0.150754,-1.569475 -0.964607,-1.603989 -0.653173,-0.0277 -1.538764,0.02241 -2.536217,0.220351 z"- id="path2995"- inkscape:connector-curvature="0"- sodipodi:nodetypes="ssscscssssccccsssssccsssccssss" />- </g>- <g- inkscape:groupmode="layer"- id="layer2"- inkscape:label="hammer"- style="display:inline">- <path- style="display:inline;fill:#768181;fill-opacity:1;stroke:none"- d="m 35.647554,14.202694 c -0.858119,2.442447 -3.971389,15.79193 -3.971389,15.79193 L 29.559208,29.3819 c 0,0 0.07894,-0.163559 4.672387,-15.501739 0.247963,-1.21401 -1.108041,-2.821158 -3.488232,-0.525961 0.401775,-1.92004 2.621814,-2.979331 4.630496,-2.261381 0.661583,0.236465 1.124554,0.424004 1.160416,0.969684 0.06052,0.920809 0.937037,0.53754 1.184156,0.06729 0.263623,-0.501655 1.853631,0.236441 1.291679,1.694383 -0.430872,1.117869 -1.782822,1.513491 -1.963352,0.880835 -0.281657,-0.987048 -0.974388,-0.793403 -1.399204,-0.502316 z"- id="path3773"- inkscape:connector-curvature="0"- sodipodi:nodetypes="cccccsssssc" />- </g>- <g- inkscape:groupmode="layer"- id="layer3"- inkscape:label="beak top"- style="display:inline">- <path- sodipodi:nodetypes="cccc"- inkscape:connector-curvature="0"- id="use3809"- d="m 39.090905,19.600911 c 0,0 -4.256138,-0.524151 -6.611684,-1.976858 2.313795,-0.105189 5.893645,0.283499 5.893645,0.283499 z"- style="opacity:0.92000002000000003;fill-opacity:1;stroke:none;fill:#000000" />- </g>-</svg>