funcons-intgen (empty) → 0.2.0.1
raw patch · 25 files changed
+4453/−0 lines, 25 filesdep +basedep +containersdep +directorysetup-changed
Dependencies added: base, containers, directory, filepath, funcons-tools, funcons-values, gll, iml-tools, mtl, pretty, regex-applicative, split, text, uu-cco
Files
- LICENSE +20/−0
- Setup.hs +2/−0
- funcons-intgen.cabal +56/−0
- src/Main.hs +78/−0
- src/Parsing/Lexer.hs +217/−0
- src/Parsing/Mutual.hs +63/−0
- src/Parsing/Rule.hs +102/−0
- src/Parsing/Spec.hs +161/−0
- src/Parsing/Syntax.hs +41/−0
- src/Parsing/Term.hs +97/−0
- src/Print/HaskellModule.hs +572/−0
- src/Print/Util.hs +142/−0
- src/Simplify/ConcreteToAbstract.hs +364/−0
- src/Simplify/CoreToTarget.hs +174/−0
- src/Simplify/LiftStrictness.hs +63/−0
- src/Simplify/Simplifier.hs +460/−0
- src/Simplify/TargetToFunconModules.hs +124/−0
- src/Simplify/TargetToIML.hs +737/−0
- src/Simplify/Utils.hs +49/−0
- src/Types/Bindings.hs +78/−0
- src/Types/ConcreteSyntax.hs +311/−0
- src/Types/CoreAbstractSyntax.hs +162/−0
- src/Types/FunconModule.hs +68/−0
- src/Types/SourceAbstractSyntax.hs +183/−0
- src/Types/TargetAbstractSyntax.hs +129/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 L. Thomas van Binsbergen++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ funcons-intgen.cabal view
@@ -0,0 +1,56 @@+name: funcons-intgen+version: 0.2.0.1+synopsis: Generate Funcons interpreters from CBS description files+homepage: http://plancomps.org+license: MIT+license-file: LICENSE+author: L. Thomas van Binsbergen <ltvanbinsbergen@acm.org>, Neil Sculthorpe <n.a.sculthorpe@swansea.ac.uk>+maintainer: L. Thomas van Binsbergen <ltvanbinsbergen@acm.org>+copyright: Copyright (C) 2015 L. Thomas van Binsbergen and Neil Schulthorpe+category: Compilers+build-type: Simple+cabal-version: >=1.10++executable cbsc+ main-is: Main.hs+ other-modules: Parsing.Spec,+ Parsing.Mutual,+ Parsing.Term,+ Parsing.Rule,+ Parsing.Syntax,+ Parsing.Lexer,+ Print.HaskellModule,+-- Print.JavaClasses,+-- Print.Ascii,+ Print.Util,+ Simplify.ConcreteToAbstract+ Simplify.Simplifier,+ Simplify.CoreToTarget,+ Simplify.LiftStrictness,+ Simplify.TargetToFunconModules,+ Simplify.TargetToIML,+ Simplify.Utils,+ Types.Bindings,+ Types.ConcreteSyntax,+ Types.SourceAbstractSyntax,+ Types.CoreAbstractSyntax,+ Types.TargetAbstractSyntax,+ Types.FunconModule+ build-depends: base >=4.8 && <= 5+ ,filepath >= 1.3.0+ ,directory+ ,split+ ,pretty >= 1.1.2+ ,uu-cco>=0.1.0.5+ ,text >= 1.2 && < 1.3+ ,mtl >= 2.2.1+ ,containers >= 0.5 && < 0.6+ ,funcons-tools >= 0.2.0.7+ ,gll>=0.4.0.9+ ,regex-applicative+ ,iml-tools>=0.3.0.4+ ,funcons-values >= 0.1.0.5+ hs-source-dirs: src+ default-language: Haskell2010+ ghc-options: -fwarn-incomplete-patterns+ -fwarn-unused-imports
+ src/Main.hs view
@@ -0,0 +1,78 @@+module Main where++import Parsing.Lexer (lexer)+import Parsing.Spec (parser)+import Simplify.ConcreteToAbstract (cs2as)+import Simplify.Simplifier (simplifier)+import Simplify.CoreToTarget (core2target)+import Simplify.LiftStrictness (lift_strictness)+import Simplify.TargetToIML (target2iml, stepR, mkValOpRules)+import Simplify.TargetToFunconModules (target2fmodule)+import Print.HaskellModule (cbs2module)+--import Print.JavaClasses (cbs2classes)+--import Print.Ascii (cbs2ascii)+import Types.FunconModule (FunconModule)++import IML.CodeGen.LaTeX+import IML.Printer+import IML.Trans.ProMan+import IML.Grammar.Specs (Spec(Spec),AnyDecls(ARuleDecl))++import CCO.Component (Component, ioRun)++import Control.Monad (when)+import Data.List (isPrefixOf)+import Control.Arrow ((>>>))+import System.Environment (getArgs)++main = do all_args <- getArgs+ let (options,args) = (filter pred all_args, filter (not . pred) all_args)+ where pred = isPrefixOf "--"+ case args of+ [] | any (== ("--iml-value-operations")) options ->+ run_iml (Spec (map ARuleDecl mkValOpRules)) options+ [cbsf] -> run cbsf Nothing Nothing options+ [cbsf,srcdir] -> run cbsf (Just srcdir) Nothing options+ [cbsf,srcdir,lang] -> run cbsf (Just srcdir) (Just lang) options+ _ -> putStrLn $ + "version CBS-beta\n\+ \usage: cbsc <CBS-PATH> <SRC-DIR> <LANG>\n\+ \CBS-PATH: path to the .cbs file\n\+ \ for which code is to be generated.\n\+ \ The file should be within a directory named \"Funcons\".\n\+ \SRC-DIR: the source-directory in which the code is to be generated.\n\+ \LANG: the language for which the .cbs file contains a specification.\n"++run cbsfile srcdir lang options = do+ when (not toIML) (putStrLn ("Generating " ++ cbsfile))+ cbs_contents <- readFile cbsfile+ let core2target' + | "--generate-congruences" `elem` options = core2target >>> lift_strictness+ | otherwise = core2target+ target <- ioRun (lexer >>> parser >>> cs2as pholder >>> simplifier + >>> core2target') cbs_contents+ if toIML+ then do let ran_options = IML.Trans.ProMan.runOptions options+ iml <- runComponentIO ran_options target2iml target+ run_iml iml options+ else do fmodule <- ioRun (target2fmodule pholder) target+ m_contents <- ioRun ((cbs2 options) cbsfile srcdir lang) fmodule+ case m_contents of+ Nothing -> putStrLn "No funcons, types or entities to generate"+ Just make_contents -> make_contents+ where pholder = any (== "--generate-unspecified-funcons") options+ toIML = any (== "--IML") options+ +cbs2 :: [String] -> FilePath -> Maybe FilePath -> Maybe String -> + CCO.Component.Component FunconModule (Maybe (IO ()))+cbs2 options {-| "--java" `elem` options = cbs2classes+ | "--ascii" `elem` options = cbs2ascii+ | otherwise -} = cbs2module++run_iml iml options = do+ let chain | "--LaTeX" `elem` options = spec2latex_module >>> component_ show+ | otherwise = spec2highstring+ printable <- runComponentIO (IML.Trans.ProMan.runOptions options) chain iml + putStrLn printable ++
+ src/Parsing/Lexer.hs view
@@ -0,0 +1,217 @@++module Parsing.Lexer (Parsing.Lexer.lexer, mylexer) where++import GLL.Combinators (Token(..),SubsumesToken(..))++import CCO.Component++import Data.Char (isDigit, isAlpha, isUpper, isLower, isAlphaNum, isSpace)+import Text.Regex.Applicative+import Text.Read (readEither)++lexer :: Component String [Token]+lexer = component (return . mylexer)+--lexer = component (((\x -> trace (show x) (return x))) . mylexer)++mylexer = sSpecs++-- Do not forget that states can be created that do not perform+-- longest match by default. Could help to disambiguate atoms for example.+lState :: String -> Bool -> RE Char t -> (t -> String -> [Token]) -> + (t -> Maybe Token) -> String -> [Token]+lState _ _ _ _ _ [] = []+lState stateName discardLayout myTokens mySelector adder s =+ let re | discardLayout = Just <$> myTokens <|> ws+ | otherwise = Just <$> myTokens+ ws = (Nothing <$ some (psym isSpace))+ <|> (Nothing <$ string "//" <* many (psym ((/=) '\n')))+ <|> (Nothing <$ string "#" <* many (psym ((/=) '\n')))+ in case findLongestPrefix re s of+ Just (Just tok, rest) -> (maybe id (:) (adder tok)) (mySelector tok rest)+ Just (Nothing,rest) -> lState stateName discardLayout myTokens mySelector adder rest+ Nothing -> error ("lexical error at " ++ stateName ++ ": " ++ show (take 10 s))+++sSpecs = lState "SPECS" True (lCommentStart <|> lTokens) sel Just+ where sel tok = case tok of Keyword "/*" -> sComment+ Keyword "/*HS-IMPORTS" -> sComment+ Keyword "Section" -> sSectionNum+ Keyword "Subsection" -> sSectionNum+ _ -> sSpecs++sSectionNum = lState "SECTION-NUM" True (optional lSectNum) sel id+ where sel tok = sSection ++sSection = lState "SECTION" False lTitleWords (const sSpecs) Just++sComment = lState "COMMENT" False + (lHS_import <|> lTick <|> lCommentEnd <|> lCommentPart) sel Just+ where sel tok = case tok of Token "TICK" _ -> sTickIn + Keyword "*/" -> sSpecs+ _ -> sComment+ lHS_import = Keyword <$> string "HS-IMPORTS"++sTickIn = lState "TICK-IN" True (lTick <|> lTokens) sel Just+ where sel tok = case tok of Token "TICK" _ -> sTickIn+ _ -> sSpecInTick++sTickOut = lState "TICK-OUT" False (lTick <|> lCommentPart) sel Just+ where sel tok = case tok of Token "TICK" _ -> sTickOut+ _ -> sComment++sSpecInTick = lState "SPEC-IN-TICK" True (lTick <|> lTokens) sel Just+ where sel tok = case tok of Token "TICK" _ -> sTickOut+ _ -> sSpecInTick+++lTokens :: SubsumesToken t => RE Char t+lTokens =+ lCharacters+ <|> lKeywords+ <|> charsToInt <$> optional (sym '-') <*> some (psym isDigit)+ <|> upcast . IDLit . Just <$> lName + <|> upcast . AltIDLit . Just <$> lVar +-- <|> upcast . CharLit . Just <$> lCharLit+ <|> upcast . StringLit . Just <$> lStringLit+ <|> lMore+ where+ charsToInt Nothing n = upcast (IntLit (Just (read n)))+ charsToInt (Just _) n = upcast (IntLit (Just (-(read n))))++ lChar c = upcast (Char c) <$ sym c+ lCharacters = foldr ((<|>) . lChar) empty cbs_characters++ lKeyword k = upcast (Keyword k) <$ string k+ lKeywords = foldr ((<|>) . lKeyword) empty cbs_keywords++ lMore = foldr ((<|>) . uncurry lToken) empty myTokens + lToken t re = upcast . Token t . Just <$> re++ lStringLit = toString <$ sym '\"' <*> many strChar <* sym '\"'+ where strChar = sym '\\' *> sym '\"'+ <|> psym ((/=) '\"')+ toString inner = case readEither ("\"" ++ inner ++ "\"") of+ Left _ -> inner+ Right v -> v ++ lCharLit = id <$ sym '\'' <*> charChar <* sym '\''+ where charChar = sym '\\' *> sym '\''+ <|> psym ((/=) '\'')++cbs_characters = "~():,*+?!|[]{}.@=<>-_&^"++cbs_keywords = [ "Alias"+ , "Assert"+ , "Auxiliary"+ , "Built-in"+ , "Datatype" + , "Entity" + , "Funcon"+ , "Hidden"+ , "Language"+ , "Lexis"+ , "Meta-variables"+ , "Otherwise" + , "Rule"+ , "SDF"+ , "Semantics"+ , "Syntax"+ , "Type"+ , "Variables"+ , "...", ">:", "<:", "=>", "|->", "==", "~>" + , "=/=", "|-", "--", "->", "::=", "[[", "]]"]++lCommentStart = Keyword "/*" <$ sym '/' <* sym '*'+ <|> Keyword "/*HS-IMPORTS" <$ string "/*HS-IMPORTS"+lCommentEnd = Keyword "*/" <$ sym '*' <* sym '/'++myTokens = [("ATOM", lAtom), ("FILE", lFile), ("BAR", lBar)+ ,("ORDINAL", lOrdinal), ("DQUOTE", lDQuote) ]++lDQuote = "\\\"" <$ sym '\\' <* sym '\"'++lBar = "----" <$ sym '-' <* sym '-' <* sym '-' <* sym '-' <* many (sym '-')++lName = (:) <$> psym isLower <*> many (psym (\c -> isAlphaNum c || c == '-'))++lCommentPart :: SubsumesToken t => RE Char t+lCommentPart = + upcast (Char '*') <$ sym '*'+ <|> upcast (Char '@') <$ sym '@'+ <|> upcast <$ sym '@' <*> lSectNum+ <|> upcast . Token "ORDINARY" . Just <$> lOrdinary+ ++lOrdinary = some $ psym (\c -> c /= '*' && c /= '`' && c /= '@')++--TODO atoms are not being lexed correctly+-- for example '\' | '`' should be two atoms separated by a char '|'+-- this is an interesting example of ambiguity+--+-- ambiguity: '\' '\' , one atom '\' ' followed by \', or two atoms '\'+--+-- Lexis+-- capitalized-characters ::= '\' | '`' +lAtom = sym '\'' *> ((concat <$> few atom_char) <|> lBackslash <|> escaped) <* sym '\''+ where atom_char = (:[]) <$> psym (not . invC)+-- TODO how to allow escaped single quotes in atoms (see ambiguities above)+-- <|> escaped + where invC c = c == '\'' || c == '\t' || c == '\n' || c == '\r' + -- || c == '|' {- temporary fix -}++ escaped = (\a b -> [a,b]) <$> sym '\\' <*> sym '\''+lVar = (\c xs ys zs -> c:xs++ys++zs) <$> psym isUpper <*> many (psym isAlpha) + <*> stem_rest <*> rest+ where stem_rest = (++) <$> (concat <$> many ((:) <$> sym '-' <*> some (psym isAlpha))) + <*> stem_suffix+ stem_suffix = maybe [] id <$> optional ((\a b -> [a,b]) <$> sym '-' <*> psym isDigit)+ rest = (++) <$> suffix <*> (maybe [] id <$> (optional postfix))+ where suffix = (++) <$> many (psym isDigit) <*> many (sym '\'')+ postfix = (:[]) <$> (sym '*' <|> sym '+' <|> sym '?')++lFile = ((++)) . concat <$> many part_sep <*> part+ where part = some (psym isAlphaNum)+ part_sep = (\a b -> a ++ [b]) <$> part <*> (sym '-' <|> sym '_')++lSectNum :: RE Char Token+lSectNum = Token "SECT-NUM" . Just <$> lSect1Num + <|> Token "SECT-NUM" . Just <$> lSect2Num + <|> Token "SECT-NUM" . Just <$> lSect3Num + <|> Token "SECT-NUM" . Just <$> lSect4Num ++-- ambiguity MISC lexes both as lSect1Num, but should be interpreted as lTitleWords+lSect1Num = lOrdinal+lSect2Num = (\x y z -> x++[y]++z) <$> lOrdinal <*> sym '.' <*> lOrdinal+lSect3Num = (\x1 x2 x3 x4 x5 -> x1++[x2]++x3++[x4]++x5) <$> + lOrdinal <*> sym '.' <*> lOrdinal <*> sym '.' <*> lOrdinal +lSect4Num = (\x1 x2 x3 x4 x5 x6 x7 -> x1++[x2]++x3++[x4]++x5++[x6]++x7) <$> + lOrdinal <*> sym '.' <*> lOrdinal <*> sym '.' <*> lOrdinal + <*> sym '.' <*> lOrdinal+lOrdinal = some (psym isDigit) {- CAUSES AMBIGUITY, IS IT USED? <|> (:[]) <$> psym isAlpha-}++lTitleWords :: RE Char Token+lTitleWords = Token "TITLE" . Just <$> many (psym ((/=) '\n')) <* sym '\n' ++lTick :: SubsumesToken t => RE Char t+lTick = upcast (Token "TICK" (Just "`")) <$ sym '`'++-- | Escaped backslash+lBackslash = "\\" <$ sym '\\' <* sym '\\'++concatMany :: RE Char String -> RE Char String+concatMany p = concat <$> many p ++concatSome p = concat <$> some p++{-+notFollowedBy :: RE c s1 -> RE c s2 -> RE c s1+notFollowedBy p q = do+ -- apply the regex p+ (res, matched) <- withMatched p+ case match q of --then see if the regex q matches+ Just _ -> -- if it does we need to insert `matched` back into the input string+ empty+ Nothing -> return res -- otherwise just return the result+-}++
+ src/Parsing/Mutual.hs view
@@ -0,0 +1,63 @@++module Parsing.Mutual where++import Funcons.EDSL (SeqSortOp(..))++import GLL.Combinators++import Types.ConcreteSyntax+import Parsing.Lexer (mylexer)++type Parser a = BNF Token a++debug :: Parser a -> String -> [a]+debug p = parseWithOptions [throwErrors] p . mylexer ++-- solves ambiguity B:=>booleans+pDef :: Parser String+pDef = "DEF" <:=> keyword "~>" ++pVar :: Parser Var+pVar = "VAR" <:=> Nothing <$$ keychar '_'+ <||> Just <$$> alt_id_lit + <||> Nothing <$$ keyword "..." ++pVarString :: Parser String+pVarString = "VAR" <:=> (:[]) <$$> keychar '_' <||> alt_id_lit ++pSynName :: Parser String+pSynName = "SYN-NAME" <:=> name_lit++pPostfix :: Parser SeqSortOp +pPostfix = "POSTFIX"+ <::=> StarOp <$$ keychar '*'+ <||> PlusOp <$$ keychar '+'+ <||> QuestionMarkOp <$$ keychar '?'+++-- TODO: debug pConst "\"\\\"\""+pConst :: Parser Const+pConst = "CONST"+ <:=> ConstAtom <$$> atom_lit+ <||> ConstString <$$> string_lit+ <||> ConstNat <$$> int_lit+ <||> ConstFloat <$$> float_lit -- TODO add float_lit to GLL.Combinators++-- tokens+atom_lit :: Parser String+atom_lit = token "ATOM"++name_lit :: Parser String+name_lit = id_lit++bar :: Parser String+bar = token "BAR"++file_name :: Parser String+file_name = token "FILE"++ordinal :: Parser String+ordinal = "NT-ORDINAL" <:=> token "ORDINAL" <||> (show <$$> int_lit)++double_quote :: Parser String+double_quote = token "DQUOTE"
+ src/Parsing/Rule.hs view
@@ -0,0 +1,102 @@++module Parsing.Rule where++import Parsing.Syntax+import Parsing.Mutual+import Parsing.Term+import Types.ConcreteSyntax++import GLL.Combinators++pRuleSpec :: Parser Rule+pRuleSpec = "RULE-SPEC" + <:=> keyword "Rule" **> pRule++-- ambiguity:+-- X ---> X atomic(X) ---> V ------ X ---> V+-- alternative interpretation is X ---> X atomic (X) ---> V ------- X ---> V+pRule :: Parser Rule+pRule = "RULE" + <:=> Inference [] <$$> pConclusion+ <||> Inference <$$> many pPremise <** bar <**> pConclusion+ <||> Desugar <$$> pPhrasePatt <** keychar ':' <**> pPhraseType <** + keychar '=' <**> pPhraseTerm+ <||> Semantics <$$> name_lit <**> pPhrasePatt <**> optional pTerm <**+ keychar '=' <**> pTerms++pConclusion :: Parser Conclusion+pConclusion = "CONCLUSION"+ <:=> ConcDynamic <$$> optional pContext <**> pState <**> pDynamic <**> pState+ <||> ConcTyping <$$> optional pContext <**> pState <** keychar ':' <**> pTerm+ <||> ConcStatic <$$> optional pContext <**> pState <** keychar ':' <**> + pTerm <**> pStatic <**> pState+ <||> ConcRewrite <$$> pTerm <** keyword "~>" <**> pTerm++pPremise :: Parser Premise+pPremise = "PREMISE"+ <:=> PremDynamic <$$> optional pContext <**> pState <**> pDynamic <**> pState+ <||> PremTyping <$$> optional pContext <**> pState <** keychar ':' <**> pTerm+ <||> PremStatic <$$> optional pContext <**> pState <** keychar ':' <**> + pTerm <**> pStatic <**> pState+ <||> PremRewrite <$$> pTerm <** keyword "~>" <**> pTerm+ <||> PremEquality <$$> pTerm <** keyword "==" <**> pTerm+ <||> PremInequality <$$> pTerm <** keyword "=/=" <**> pTerm+ <||> PremSubtype <$$> pTerm <** keyword "<:" <**> pTerm++pContext :: Parser Context +pContext = "CONTEXT"+ <:=> Context <$$> multipleSepBy1 pEntTerm (keychar ',') <** keyword "|-"++pPolarEntTerm :: Parser PolarEntTerm+pPolarEntTerm = "POLAR-ENT-TERM"+ <:=> (\n mp t -> (n,t,mp)) <$$> name_lit <**> optional pPolarity <**> pTerm++pEntTerm :: Parser EntTerm+pEntTerm = "ENT-TERM"+ <:=> (,) <$$> name_lit <**> pTerm ++pPolarity :: Parser Polarity+pPolarity = "POLARITY" <:=> In <$$ keychar '?' <||> Out <$$ keychar '!'++pState :: Parser State+pState = "STATE"+ <:=> StateExplicit <$$ keychar '<' <**> pTerm <** keychar ',' <**>+ multipleSepBy1 (pEntTerm) (keychar ',') <** keychar '>' + <||> StateImplicit <$$> pTerm++pDynamic :: Parser Dynamic+pDynamic = "DYNAMIC"+ <::=> DynamicExplicit <$$ keyword "--" <**> multipleSepBy1 (pPolarEntTerm) (keychar ',') <** keyword "->" <**> optional (int_lit)+ <||> DynamicImplicit <$$ keyword "--" <** keyword "->" <**> optional int_lit+ <||> DynamicComposition <$$> pDynamic <** keychar ';' <**>>> pDynamic++pStatic :: Parser Static+pStatic = "STATIC"+ <:=> StaticExplicit <$$ keyword "==" <**> multipleSepBy1 pPolarEntTerm (keychar ',')+ <** keyword "=>"+ <||> StaticImplicit <$$ keyword "==" <** keyword "=>"++pArrow :: Parser Arrow+pArrow = "ARROW"+ <:=> AStatic <$$ keyword "==" <** keyword "=>"+ <||> ADynamic <$$ keyword "--" <** keyword "->" ++pPred :: Parser Pred+pPred = "PRED"+ <:=> PredType <$$ keychar ':' <**> pTerm+ <||> PredSubType <$$ keyword "<:" <**> pTerm++pPhrasePatt :: Parser PhrasePatt+pPhrasePatt = "PHRASE-PATT"+ <:=> keyword "[[" **> pWordPatts <** keyword "]]"++pWordPatts :: Parser [WordPatt]+pWordPatts = many pWordPatt++pWordPatt :: Parser WordPatt+pWordPatt = "WORD-PATT"+ <::=> WPVar <$$> pVar+ <||> WPAtom <$$> atom_lit+ <||> WPGroup <$$> parens pWordPatts+ <||> parens (WPUnion <$$> atom_lit <** keychar '|' <**> + manySepBy1 atom_lit (keychar '|'))
+ src/Parsing/Spec.hs view
@@ -0,0 +1,161 @@+{-# LANGUAGE TupleSections #-}++module Parsing.Spec where++import Parsing.Term+import Parsing.Mutual+import Parsing.Rule+import Parsing.Syntax+import Types.ConcreteSyntax++import CCO.Component++import GLL.Combinators+++parser :: Component [Token] CBSFile+parser = component (return . head . parseWithOptions [throwErrors, maximumPivot] pCBS)++pCBS :: Parser CBSFile+pCBS = "CBS-FILE"+ <:=> optional (keyword "Language" <** string_lit) **> pManySpecs++pManySpecs :: Parser [CBSSpec]+pManySpecs = "MANY-SPECS"+ <::=> (:) <$$> pComment <**> pManySpecs --comments+ <||> id <$$ keyword "Assert" <** pPremise <**> pManySpecs -- discard assertions+ <||> id <$$ keyword "Built-in" <** pSpec <**> pManySpecs -- ignore built-ins + <||> (:) <$$> pSpec <**> pManySpecs+ <||> id <$$ brackets (multiple pRef) <**> pManySpecs+ <||> satisfy []++pRef :: Parser String+pRef = "RefKindName" <:=> pKind <** id_lit++pSpec :: Parser CBSSpec+pSpec = "SPEC" + <::=> keyword "Auxiliary" **> pSpec+ <||> pFuncon+ <||> pSyntaxSpec+ <||> pSemanticsSpec+ <||> RuleSpec <$$> pRuleSpec+ <||> AliasSpec <$$ keyword "Alias" <**> id_lit <** keychar '=' <**> id_lit + <||> OtherwiseSpec <$$ keyword "Otherwise" <**> pRule+ <||> TypeSpec <$$ keyword "Type" <**> id_lit <**> optional pParams <**> multiple pBounded <**> optional pDefRewrite+ <||> DatatypeSpec <$$ keyword "Datatype" <**> id_lit <**> optional pParams <**>+ optional pBounded <**> optionalWithDef (keyword "::=" **> pDataAlts) []+ <||> EntitySpec <$$ keyword "Entity" <**> pEntityDecl+ <||> MetaVariablesSpec . concat <$$ keyword "Meta-variables" <**> (many1 pVarDecl)++pVarDecl :: Parser [VarDecl]+pVarDecl = "VARS-DECL"+ <:=> apply <$$> manySepBy1 alt_id_lit (keychar ',') <**> + (Left <$$ keyword "<:" <**> pTerm <||>+ Right <$$ keychar ':' <**> pTerm)+ where apply vars (Left ty) = map (flip VarDeclSubType ty) vars+ apply vars (Right ty) = map (flip VarDeclType ty) vars++pFuncon :: Parser CBSSpec +pFuncon = "FUNCON" + <::=> build_funcon <$$ keyword "Funcon" <**> id_lit + <**> optional pParams + <** keychar ':'+ <**> pTerm + <**> optional pDefRewrite+ where build_funcon nm mparams cs = FunconSpec nm mparams cs ++pSemanticsSpec :: Parser CBSSpec+pSemanticsSpec = "SEMANTICS"+ <:=> SemanticsSpec <$$ keyword "Semantics" <**> name_lit <** keyword "[[" <**>+ pVar <** keychar ':' <**> pPhraseType <** keyword "]]" <**> + optional pParams <** keychar ':' <**> pTerm <**> optional pDefEqual++-- ambiguity "(X:T,Y:T)+-- alternative interpretation: +pParams :: Parser Params+pParams = "PARAMS"+ <::=> keychar '(' **> multipleSepBy pParam (keychar ',') <** keychar ')'++pParam :: Parser Param+pParam = "PARAM"+ <::= Param <$$> pVar <**> optional pBounded++pDefEqual :: Parser DefEqual+pDefEqual = "DEFINED-EQUAL" <::=> DefEqual <$$ keychar '=' <**> pTerm+pDefRewrite :: Parser DefRewrite+pDefRewrite = "DEFINED-REWRITE" <::=> DefRewrite <$$ keyword "~>" <**> pTerm++pBounded :: Parser Bounds +pBounded = "BOUNDED" + <:=> InType <$$ keychar ':' <**> pType+ <||> Sub <$$ keyword ">:" <**> pType+ <||> Sup <$$ keyword "<:" <**> pType ++pDataAlts :: Parser [DatatypeAlt]+pDataAlts = "ALT+ |" <:=> multipleSepBy pDataAlt (keychar '|')++pDataAlt :: Parser DatatypeAlt+pDataAlt = "ALT" + <:=> AltDots <$$ keyword "..."+ <||> Inj <$$ keychar '{' <**> pVar <** keychar ':' <**> pType <** keychar '}'+ <||> Cons <$$> id_lit <**> optional pParams ++pEntityDecl :: Parser Entity+pEntityDecl = "ENTITY"+ <:=> EntContextual <$$> pEnt <** keyword "|-" <** keychar '_' <**> pArrow+ <** keychar '_'+ <||> EntMutable <$$> angles ((keychar '_' **> keychar ',') **> pEnt) <**> + pArrow <**> + angles ((keychar '_' **> keychar ',') **> pEnt)+ <||> EntObservable <$$ keychar '_' <**> pEntArrow <** keychar '_'++pEnt :: Parser Ent+pEnt = "ENT"+ <:=> EntVarStem <$$> pVarStem <**> optional (pPolarity)+ <||> EntName <$$> name_lit <**> optional pPolarity <** + keychar '(' <**> pVar <** keychar ':' <**> pTerm <** keychar ')'++pEntArrow :: Parser EntArrow+pEntArrow = "ENT-ARROW"+ <:=> EADynamic <$$ keyword "--" <**> pEnt <** keyword "->" + <||> EAStatic <$$ keyword "==" <**> pEnt <** keyword "=>"++pComment :: Parser CBSSpec +pComment = "COMMENT" + <:=> CommentSpec <$$ keyword "/*" <**> multiple pCommentPart <** keyword "*/"+ <||> MetaSpec . HS_Imports <$$ keyword "/*HS-IMPORTS" + <**> token "ORDINARY" <** keyword "*/"++pCommentPart :: Parser CommentPart+pCommentPart = "COMMENT-PART" + <::=> Ordinary <$$> token "ORDINARY" + <||> Asterisk <$$ keychar '*'+ <||> At <$$ keychar '@' <**> optionalWithDef (token "SECT-NUM") ""+ <||> At <$$> token "SECT-NUM"+ <||> CommentTerm <$$ token "TICK" <**> multipleSepBy1 pTerm (keychar ',') <** token "TICK"+ <||> CommentPremise <$$ token "TICK" <** token "TICK" <**> pPremise+ <** token "TICK" <** token "TICK"+ <||> SpecInComment <$$ token "TICK" <** token "TICK" <** token "TICK"+ <**> pSpec + <** token "TICK" <** token "TICK" <** token "TICK"++-- sections+pKind :: Parser String+pKind = "KIND" <:=> + keyword "Funcon" <||> keyword "Type" <||> keyword "Datatype" <||> + keyword "Entity" <||> keyword "Lexis" <||> keyword "Syntax" <||> + keyword "Semantics" <||> keyword "Alias"++-- related to syntax+pSyntaxSpec :: Parser CBSSpec+pSyntaxSpec = "SYNTAX-SPEC" + <:=> SyntaxSpec <$$ keyword "Syntax" <**> multiple1 pProd+ <||> LexisSpec <$$ keyword "Lexis" <**> multiple1 pProd++pProd :: Parser Prod+pProd = "PROD"+ <:=> Prod <$$> optionalWithDef (pVarStems) [] <**> pSynName <** + keyword "::=" <**> pAlts + <||> SDFComment [] <$$ keyword "SDF" <** pComment++
+ src/Parsing/Syntax.hs view
@@ -0,0 +1,41 @@++module Parsing.Syntax where++import Types.ConcreteSyntax++import Parsing.Mutual++import GLL.Combinators++pVarSynName :: Parser VarSynName+pVarSynName = "VAR-SYN-NAME" + <:=> VarName <$$> pVarString <** keychar ':' <**> name_lit+ <||> SynName <$$> name_lit++pVarStems :: Parser [VarStem]+pVarStems = "VAR-STEMS"+ <:=> multipleSepBy1 pVarString (keychar ',') <** keychar ':'++pVarStem :: Parser VarStem+pVarStem = "VAR-STEM" <:=> pVarString ++pAlts :: Parser PhraseType+pAlts = "PT-ALTS" <:=> foldr1 PTUnion <$$> multipleSepBy1 pAlt (keychar '|')++pAlt :: Parser PhraseType+pAlt = "SINGLE-PT-ALT" <:=> foldr1 PTSeq <$$> multiple1 pPhraseType++pPhraseType :: Parser PhraseType+pPhraseType = "PHRASE-TYPE"+ <::=> PTSynName <$$> pSynName+ <||> atom_or_range <$$> atom_lit <**> optional (keychar '-' **> atom_lit)+ <||> PTComplement <$$ keychar '~' <**> pPhraseType+ <||> flip ($) <$$> pPhraseType <**> pPhraseTypeRest+ <||> PTGroup <$$> parens (optional pAlts)+ where atom_or_range a1 (Just a2) = PTRange a1 a2+ atom_or_range a1 Nothing = PTAtom a1++pPhraseTypeRest :: Parser (PhraseType -> PhraseType)+pPhraseTypeRest = "REST-PHRASE-TYPE"+ <::=> flip PTPostfix <$$> pPostfix+ <||> flip PTNoLayout <$$ keychar '_' <**> pPhraseType
+ src/Parsing/Term.hs view
@@ -0,0 +1,97 @@++module Parsing.Term where++import Parsing.Mutual+import Types.ConcreteSyntax++import GLL.Combinators++pType :: Parser Type+pType = "TYPE" <:=> pTerm++-- ambiguity:+-- S=>T (alternative interpretation S applied to =>)+pTerm :: Parser Term +pTerm = "TERM"+ <::= SemanticsApp <$$> name_lit <**> pPhraseTerm <**> optional pTerm+ <||> TermConst <$$> pConst+ <||> TermVar <$$> pVar + <||> TermDots <$$ keyword "..."+ <||> TermName <$$> name_lit+ -- ambiguity "X:T,Y:T" (non-associative, no nesting)+ <||> Typed <$$> pTerm <** keychar ':' <**> pType+ <||> Computes <$$ keyword "=>" <**> pType+ <||> ComputesFrom <$$> pType <** keyword "=>" <**> pType + <||> TermComplement <$$ keychar '~' <**> pTerm+ <||> TermPostfix <$$> pType <**> pPostfix+ <||> TermUnion <$$> pTerm <** keychar '|' <**>>> pTerm+ <||> TermInter <$$> pTerm <** keychar '&' <**>>> pTerm + <||> termTuple <$$ keychar '(' <**> pTerms <** keychar ')'+ <||> TermList <$$ keychar '[' <**> pTerms <** keychar ']'+ <||> TermSet <$$ keychar '{' <**> pTerms <** keychar '}'+ <||> TermMap <$$ keychar '{' <**> pPoints <** keychar '}'+ <||> TermPower <$$> pTerm <** keychar '^' <**> pTerm+-- <||> pTermSeq {- replaced by specific occurrence as rhs of semantics spec -}+ <||> NameApp <$$> name_lit <**> pTerm+ <||> VarApp <$$> pVar <**> pTerm+ <||> double_quote **> pTerm <** double_quote+{-+pTermSeq :: Parser Term+pTermSeq = "TERMS" <::=> + merge <$$> pTerm <**> optional (keychar ',' **> pTermSeq)+ <||> satisfy (TermSequence [])+ where merge t (Just (TermSequence ts)) = TermSequence (t:ts)+ merge t1 (Just t2) = TermSequence [t1,t2]+ merge t1 Nothing = t1+-}+-- obvious ambiguity (associativity)+-- 1,2,3 (why does manySepBy2 not resolve this?)+pTermSeq :: Parser Term+pTermSeq = "TERMSEQ" <:=> shortest_match (TermSequence <$$> multipleSepBy2 pTerm (keychar ','))++-- obvious ambiguity (associativity)+-- 1,2,3 (why does manySepBy2 not resolve this?)+-- TODO generalise type argument of first parameter of rassoc?+pTerms :: Parser [Term]+pTerms = "TERMS" <:=> shortest_match (manySepBy pTerm (keychar ',') <** satisfy ())++pTermUnions :: Parser [Term]+pTermUnions = "TERMUNIONS" <::=> + (:) <$$> pType <** keychar '|' <**> pTermUnions0 + where pTermUnions0 = "0TERMUNIONS" <:=>+ (:[]) <$$> pType+ <||> pTermUnions++pTermInters :: Parser [Term]+pTermInters = "TERM-INTERS" <::=> + (:) <$$> pType <** keychar '&' <**> pTermInters0 + where pTermInters0 = "0TERM-INTERS" <:=>+ (:[]) <$$> pType+ <||> pTermInters+++{-+pTermUnions :: Parser [Term]+pTermUnions = "TERMUNIONS" <:=> multipleSepBy1 pType (keychar '|')+-}++-- | Key-Value pairs of terms in a map+-- pair is optional, can be given as ...+pPoints :: Parser [Maybe (Term, Term)]+pPoints = "POINTS" <:=> multipleSepBy1 pPair (keychar ',')+ where pPair :: Parser (Maybe (Term, Term))+ pPair = "PAIR" <:=> (Just .) . (,) <$$> pTerm <** keyword "|->" <**> pTerm+ <||> Nothing <$$ keyword "..."++pPhraseTerm :: Parser PhraseTerm+pPhraseTerm = "PHRASE-TERM"+ <:=> keyword "[[" **> pWordTerms <** keyword "]]"++pWordTerms :: Parser [WordTerm]+pWordTerms = many pWordTerm ++pWordTerm :: Parser WordTerm+pWordTerm = "WORD-TERM"+ <::=> WTVar <$$> pVar+ <||> WTAtom <$$> atom_lit+ <||> WTGroup <$$> parens pWordTerms
+ src/Print/HaskellModule.hs view
@@ -0,0 +1,572 @@+{-# LANGUAGE LambdaCase #-}+-- many opportunities for small optimisations+-- e.g. do not apply (map text), gList, nameOfSig, stepTypeOfSig, etc. multiple times+module Print.HaskellModule where++import Funcons.EDSL (Funcons(..),DataTypeMembers(..), f2vPattern)++import Print.Util+import Types.ConcreteSyntax (showConcreteTerm)+import Types.SourceAbstractSyntax hiding (CBSFile(..),CBSSpec(..),FunconSpec(..),FSig,FStep,FPremiseStep,FValueSorts(..),Name,FValueSort(..),EntitySpec(..),FSideCondition(..),DataTypeSpec(..),FTerm(..),DataTypeAlt(..),FValSorts(..),FPattern(..), CommentPart(..))+import Types.CoreAbstractSyntax hiding (Lazy, Strict, CBSFile(..),CBSSPec(..),FunconSpec(..),FRewriteRule(..),FPremiseStep(..),FStep(..),FStepRule(..), DataTypeSpec(..), DataTypeAlt(..))+import qualified Types.CoreAbstractSyntax as C+import Types.FunconModule as F+import Types.TargetAbstractSyntax (InputAccess(..))++import CCO.Component++import Prelude hiding ((<$>))++import Control.Monad (unless)+import Data.Maybe (catMaybes)+import Data.List(intercalate, findIndices)+import Data.List.Split (splitOn)+import Data.Char (toUpper, isUpper, toLower)+import Text.PrettyPrint.HughesPJ+import Data.Text(pack,unpack)++import System.FilePath hiding ((<.>)) +import qualified System.FilePath as FP+import System.Directory (createDirectoryIfMissing, doesFileExist)++type Name = String+type StepName = Name -- name of a step function++cbs2module :: FilePath -> Maybe FilePath -> Maybe String -> + Component FunconModule (Maybe (IO ()))+cbs2module cbsfile msrcdir mlang = component (\cbsfile -> return $+ let mfiledoc = fmap ((gHeader modName $+$)) $+ gFile (aliases cbsfile)+ (funcons cbsfile)+ (entities cbsfile)+ (datatypes cbsfile)+ + in (fmap doPrint mfiledoc))+ where render' filedoc = render (text "-- GeNeRaTeD fOr:" <+> text cbsfile $+$ filedoc)+ doPrint doc = case (msrcdir, mlang) of+ (Just srcdir, Just lang) -> do + main_exists <- doesFileExist (srcdir </> "Main.hs")+ unless main_exists $ do+ createDirectoryIfMissing False srcdir+ writeFile (srcdir </> "Main.hs") main_contents+ putStrLn "Generated Main.hs"+ createDirectoryIfMissing True hs_file_dir + writeFile hs_file (render' doc)+ putStrLn ("Generated " ++ hs_file)+ where hs_file_dir = srcdir </> foldr (</>) "" hs_file_dir_as_list + hs_file = hs_file_dir </> hs_file_name FP.<.> "hs"+ main_contents = "import Funcons.Tools (mkMainWithLibraryEntitiesTypes)\n\+ \import Funcons." ++ camelcase lang ++ ".Library\n" + (Just srcdir, _) -> do + writeFile (srcdir </> hs_file_name FP.<.> "hs") (render' doc)+ putStrLn ("Generated " ++ (hs_file_name FP.<.> "hs"))+ _ -> putStrLn (render' doc) --simply print to stdout + lang = maybe "Core" id mlang+ modName = case mlang of Nothing -> Nothing+ _ -> Just (intercalate "." modNameAsList)+ modNameAsList = hsmodNameFromPath lang cbsfile+ hs_file_name = last modNameAsList + hs_file_dir_as_list = init modNameAsList++gHeader :: Maybe String -> Doc+gHeader mmodname = vsep $+ [text "{-# LANGUAGE" <+> text "OverloadedStrings" <+> text "#-}"] +++ (maybe [] (\nm -> [text "module" <+> text nm <+> text "where"]) mmodname) +++ [text "import" <+> text "Funcons.EDSL"+ ,text "import" <+> text "Funcons.Operations" <+> text "hiding" <+> parens (text "Values" <> comma <> text "libFromList")] ++ + (maybe [text "import" <+> text "Funcons.Tools"] (const []) mmodname)+ +gFile :: AliasMap -> [FunconSpec] -> [EntitySpec] -> [DataTypeMembers] -> Maybe Doc+gFile als fspecs especs dspecs+ | null fspecs && null especs && null dspecs = Nothing+ | otherwise = Just $+ vsep $+ [text fEntities <=> gList [] -- {- defaults have been removed from beta -} + ,text fTypes <=> text ftypeEnvFromList $+$+ nest 4 (gList (concatMap (gTypes als) dspecs))+ ,text fFuncons <=> text fLibFromList $+$+ nest 4 (gList lib_entries)]+ ++ map (gStep als) fspecs+-- ++ concatMap (\(DataTypeDecl _ _ alts) -> map gCons alts) dspecs+ ++ map gData dspecs+ where lib_entries = concatMap (gLibF als) fspecs + ++ concatMap (gLibD als) dspecs +-- ++ concatMap (gLibC als) dspecs++ gLibF :: AliasMap -> FunconSpec -> [Doc]+ gLibF als (F.FunconSpec name sig _ _ _) = + [ gTuple [gString alias+ ,gStepType steptype <+> text (stepName name)]+ | alias <- my_aliases name als ]+ where steptype = stepTypeOfSig sig++ gLibD :: AliasMap -> DataTypeMembers -> [Doc]+ gLibD als (DataTypeMemberss _ _ []) = []+ gLibD als (DataTypeMemberss nm tyargs _) = + [ gTuple [gString alias+ ,gStepType steptype <+> text (stepName (unpack nm))]+ | alias <- my_aliases (unpack nm) als ]+ where steptype | null tyargs = Nullary+ | otherwise = Strict++gData :: DataTypeMembers -> Doc+gData (DataTypeMemberss nm' tyargs _) = + text (smart_cons_name nm) <=> smart_body $+$+ text sname <+> tyarg_pat <=> main+ where nm = unpack nm'+ sname = stepName nm+ main = text frewriteType <+> gString nm <+> tyarg+ tyarg_pat | null tyargs = empty+ | otherwise = text "ts"+ tyarg | null tyargs = brackets empty+ | otherwise = text "ts"+ smart_body + | null tyargs = text cFunconName <+> gString nm+ | otherwise = text cFunconApp <+> gString nm ++{-+gCons :: DataTypeAlt -> Doc+gCons (DataTypeInclusion _) = empty+gCons (DataTypeConstructor nm args strictns) =+ text (smart_cons_name nm) <=> smart_body $+$ + text sname <+> args_pat <=> main+ where args_pat | null args = empty+ | otherwise = text "fs"+ sname = stepName nm+ main = text fRewritten <+> parens return_val+ where return_val = text cADTVal <+> gString nm <+> arg+ where arg | null args = brackets empty+ | all isStrict strictns = + parens (text "fvalues" <+> text "fs")+ | otherwise = text "fs"+ smart_body = case args of + [] -> text cFunconName <+> gString nm+ _ -> text cFunconApp <+> gString nm+-}++gStep :: AliasMap -> FunconSpec -> Doc+gStep als fspec@(F.FunconSpec fname fsig mdoc r_rules s_rules) =+ ppMaybeDoc mdoc $+$+ vcat [ text (smart_cons_name name) <+> smart_fargs_var <=> smart_body+ | name <- my_aliases fname als ] $+$+ case steptype of+ Nullary -> text sname <=> main $+$ whereClause+ _ -> text sname <+> text fargs_var <+> text "=" $+$+ nest 4 main $+$+ whereClause+ where sname = stepName fname+ steptype = stepTypeOfSig fsig+ nullary = case steptype of Nullary -> True+ _ -> False+ smart_fargs_var | nullary = empty+ | otherwise = text "fargs"+ smart_body = case steptype of+ Nullary -> text cFunconName <+> gString fname + _ -> gFunconApp fname (text fargs_var)+++ main | null r_rules && null s_rules = text fNorule <+> selfApp+ --TODO ignore rewrites or steps if null+ | otherwise = text fEvalRules <+> + mkList "rewrite" [1..length r_rules] <+>+ mkList "step" [1..length s_rules]+ where mkList str = gList . map (\i -> text (str ++ show i))++ args = case steptype of+ Lazy i is _ -> generateArgs i+ _ -> error "fargs_var only specified for lazy funcons"++ selfApp = parens $ case steptype of+ Nullary -> text cFunconName <+> gString fname + Strict -> gFunconApp fname (parens (text ffvalues <+> text fargs_var))+ _ -> gFunconApp fname (text fargs_var)++ whereClause | null r_rules && null s_rules = empty+ | otherwise = nest 4 (text "where" <+> nest 2+ (rewriteRules (zip [1..] r_rules) $+$+ stepRules (zip [1..] s_rules)))++ rewriteRules :: [(Int, [FRewriteStmt])] -> Doc+ rewriteRules rules = vcat (map rewriteRule rules)+ rewriteRule (idx, stmts) = rule $ initEnv $+$+ vcat (map (ppRewriteStmt steptype False) stmts)+ where rule :: Doc -> Doc+ rule = ppDoBinding (text ("rewrite" ++ show idx)) []++ stepRules :: [(Int, [FStepStmt])] -> Doc+ stepRules rules = vcat (map (stepRule) rules)+ stepRule (idx, stmts) = rule $ initEnv $+$ ppStepStmts steptype stmts+ where+ rule = ppDoBinding (text ("step" ++ show idx)) []++ initEnv = text "let" <+> text env_var <=> text empty_env++ppDoBinding :: Doc -> [Doc] -> Doc -> Doc+ppDoBinding nm args body = nameWithArgs <=> text "do" $$ nest 2 body+ where nameWithArgs = hsep (nm : args)++ppLetDoBinding :: Doc -> [Doc] -> Doc -> Doc+ppLetDoBinding nm args body = text "let" <+> ppDoBinding nm args body++ppBranches rec fnm bs = + vcat (zipWith printLet [1..] bs) $+$ + text fnm <+> gList (zipWith printCall [1..] bs)+ where printLet i b = ppLetDoBinding (printCall i b) [] + (vcat (map rec b))+ printCall i b = text ("branch" ++ (show i)) <+> text env_var++ppRewriteStmt :: StepType -> Bool -> FRewriteStmt -> Doc+ppRewriteStmt stype lift stmt = case stmt of + RBranches bs -> ppBranches (ppRewriteStmt stype False) "rewriteRules" bs+ ArgsPattern _ _ | Nullary <- stype -> empty+ ArgsPattern var pats -> + text env_var <<-> text matcher <+> text var <+> ppPatterns pats <+> text env_var+ EnvStore var term -> + text env_var <<-> text envStore <+> gString var <+> parens (ppTerm term) <+> text env_var+ EnvRewrite var -> text env_var <<-> text envRewrite <+> gString var <+> text env_var+ CheckSideCondition side -> ppSideCondition checker side+ where checker | lift = lifted_fSideCondition+ | otherwise = fSideCondition+ RewriteTarget term -> text fRewTermTo <+> parens (ppTerm term) <+> text env_var+ where matcher | strict, lift = fliftvsMatch+ | strict = fvsMatch + | lift = fliftfsMatch+ | otherwise = ffsMatch+ ppPatterns | strict = ppVPatterns+ | otherwise = ppFPatterns+ envRewrite | lift = fliftEnvRewrite+ | otherwise = fEnvRewrite+ envStore | lift = fliftEnvStore+ | otherwise = fEnvStore+ strict = stepTypeStrict stype++ppStepStmts :: StepType -> [FStepStmt] -> Doc+ppStepStmts stype = vcat . map (ppStepStmt stype)++ppStepStmt :: StepType -> FStepStmt -> Doc+ppStepStmt stype = ppStepStmt' True+ where+ ppStepStmt' nocont stmt = case stmt of+ SBranches bs -> ppBranches (ppStepStmt stype) "stepRules" bs+ PremiseBlock s -> ppStepStmt' nocont s+ StepTarget term -> text fStepTermTo <+> parens (ppTerm term) <+> text env_var+ ReadInherited nm pats -> readInh nm pats+ ReadInput nm pats -> readInputs nm pats+ WriteMutable nm term -> writeMutable nm term+ ReadMutable nm pat -> readInhMut fgetMUTPatt nm pat+ WriteOutput nm term -> writeOutput nm term+ WriteControl nm mterm -> writeControl nm mterm+ -- these stmts are applied to a continuation+ -- the first of which should receive the env (e.g. env <- ...)+ ScopeInherited nm term cont -> + (if nocont then receive_result else id) $ + text fWithINHTerm <+> gString nm <+> parens (ppTerm term) <+> + text env_var <$> ppStepStmt' False cont+ ScopeInput nm terms acc cont -> + (if nocont then receive_result else id) $ + text withInput <+> gString nm <+>+ gList (map ppTerm terms) <+> text env_var <$> ppStepStmt' False cont+ where withInput = case acc of + ExactInput -> fwithExactInput+ ExtraInput -> fwithExtraInput+ ScopeDownControl nm mterm cont -> + (if nocont then receive_result else id) $ + text fWithCTRLTerm <+> gString nm <+> parens (ppMaybeTerm mterm) <+>+ text env_var <$> ppStepStmt' False cont+ ReceiveControl nms cont | nocont -> + gTuple [text env_var, gList (map sig_var nms)] <<-> + text "receiveSignals" <+> gList (map gString nms) <$> ppStepStmt' False cont + | otherwise -> error "assert ppStepStmt ReceiveControl"+ ReadControl nm mpat -> + (if nocont then receive_result else id) $ + text "receiveSignalPatt" <+> sig_var nm <+> + parens (ppMVPattern mpat) <+> text env_var + ReadDownControl nm mpat -> + text env_var <<-> text fgetDCTRLPatt <+> gString nm <+> parens (ppMaybeVPattern mpat) <+> text env_var+ ReceiveOutput nm pat cont -> + (if nocont then receive_result else id) $ + text freadOUTPatt <+> gString nm<+> + parens (ppVPattern pat) <$> ppStepStmt' False cont+ FRewriteStmt stmt -> ppRewriteStmt stype True stmt+ Premise term pats -> + (if nocont then receive_result else id) $ + text fpremise <+> parens (ppTerm term) <+> + (ppFPatterns pats) <+> text env_var+ where receive_result :: Doc -> Doc+ receive_result doc = text env_var <<-> doc++ sig_var sigNm = text ("__var" ++ var2id sigNm)++gTypes :: AliasMap -> DataTypeMembers -> [Doc]+gTypes alt (DataTypeMemberss nm' params []) = []+gTypes als (DataTypeMemberss nm' params alts) =+ [ gTuple [gString alias, gType (DataTypeMemberss (pack alias) params alts)]+ | alias <- my_aliases nm als ]+ where nm = unpack nm'+ gType :: DataTypeMembers -> Doc+ gType = text . show++readInputs :: Name -> [FPattern] -> Doc+readInputs nm pats = vcat (map readInput pats)+ where readInput pat = text env_var <<-> text fmatchInput <+> + gString nm <+> parens (ppVPattern pat) <+> text env_var ++readInh :: Name -> [FPattern] -> Doc+readInh nm pat = text env_var <<-> text fgetINHPatt <+> + gString nm <+> ppVPatterns pat <+> text env_var++readInhMut :: String -> Name -> FPattern -> Doc+readInhMut entitytype nm pat = text env_var <<-> text entitytype <+> + gString nm <+> parens (ppVPattern pat) <+> text env_var++writeMutable :: Name -> FTerm -> Doc+writeMutable nm term = text fputMUTTerm <+> gString nm <+> + parens (ppTerm term) <+> text env_var++writeControl :: Name -> (Maybe FTerm) -> Doc+writeControl nm mterm = case mterm of+ Nothing -> empty+ Just term -> text fraiseTerm <+> gString nm <+>+ parens (ppTerm term) <+> text env_var++writeOutput :: Name -> FTerm -> Doc+writeOutput nm term = text fwriteOUTTerm <+> gString nm <+>+ parens (ppTerm term) <+> text env_var++ppFuncons :: Funcons -> Doc+ppFuncons f = text (show f)++ppMaybeTerm :: Maybe FTerm -> Doc+ppMaybeTerm = text. show++-- | Sequence operators are ignore in pattern annotations+ppSort :: FTerm -> Doc+ppSort (TSortSeq sort op) = ppSort sort+ppSort term = ppTerm term++ppTerm :: FTerm -> Doc+ppTerm term = text (show term)++ppSideCondition :: String -> FSideCondition -> Doc+ppSideCondition checker sc = text env_var <<-> text checker <+> parens cond <+> text env_var+ where cond = case sc of+ SCEquality term1 term2-> text cSCEquality <+>+ parens (ppTerm term1) <+> parens (ppTerm term2)+ SCInequality term1 term2-> text cSCInequality <+>+ parens (ppTerm term1) <+> parens (ppTerm term2)+ SCIsInSort term1 sort -> text cSCIsInSort <+>+ parens (ppTerm term1) <+> parens (ppTerm sort)+ SCNotInSort term1 sort -> text cSCNotInSort <+>+ parens (ppTerm term1) <+> parens (ppTerm sort)+ SCPatternMatch term pats -> text cSCPatternMatch <+>+ parens (ppTerm term) <+> ppVPatterns pats+ -- We no longer allow this+ -- SCPatternMismatch term pat -> text cSCPatternMismatch <+>+ -- parens (ppTerm term) <+> parens (ppVPattern pat)++ppMaybeDoc :: Maybe [CommentPart] -> Doc +ppMaybeDoc Nothing = empty+ppMaybeDoc (Just cs) = text "-- |" $+$ + vcat (map ((text "-- " <>) . text) (lines (concatMap ppCommentPart cs)))++ppCommentPart :: CommentPart -> String+ppCommentPart cp = case cp of + Ordinary c -> c+ Asterisk -> "*"+ At s -> "@" ++ s+ CommentTerm ts -> "`" ++ intercalate "," (map showConcreteTerm ts) ++ "`"+ CommentPremise p -> "<PREMISE>"+ SpecInComment s -> "\n" ++ show s ++ "\n"++ppMVPattern :: Maybe FPattern -> Doc+ppMVPattern Nothing = text cNothing+ppMVPattern (Just pat) = text cJust <$> ppVPattern pat ++ppVPattern :: FPattern -> Doc+ppVPattern = text . show . f2vPattern + +ppVPatterns :: [FPattern] -> Doc+ppVPatterns pats = gList (map ppVPattern pats)++ppFPatterns :: [FPattern] -> Doc+ppFPatterns pats = gList (map ppFPattern pats)++ppMaybeVPattern :: Maybe FPattern -> Doc+ppMaybeVPattern Nothing = text "Nothing"+ppMaybeVPattern (Just pat) = text "Just" <+> parens (ppVPattern pat) ++ppFPattern :: FPattern -> Doc+ppFPattern = text . show ++-- |+-- Fake a curried smart constructor for the given funcon (name).+-- useful for congruence rules and other helpers that require a+-- smart constructor argument.+gFunconApp :: Name -> Doc -> Doc+gFunconApp nm args = text cFunconApp <+> gString nm <+> parens args++stepName :: Name -> Name+stepName = stepName' . var2id+ where stepName' "" = error "empty name"+ stepName' (hd:tl) = "step" ++ (toUpper hd : tl)++-- gathering information+data StepType = Strict+ | Lazy Int [Int] (Maybe Strictness)-- number of args + indices of value-arguments+ | Nullary++stepTypeStrict :: StepType -> Bool+stepTypeStrict Strict = True+stepTypeStrict _ = False++gStepType Strict = text cStrictF+gStepType Nullary = text cNullaryF+gStepType (Lazy args stricts mstrict) + | null stricts, Nothing <- mstrict = text cNonStrictF+ | otherwise = text cPartialLazyF <+> gList (map rep [0..args-1])+ <+> (maybe (text cNonStrict) op mstrict)+ where rep i | i `elem` stricts = op C.Strict+ | otherwise = op C.Lazy + op C.Strict = text cStrict+ op C.Lazy = text cNonStrict++stepTypeOfSig :: FSig -> StepType+stepTypeOfSig FStrict = Strict+stepTypeOfSig FLazy = Lazy 0 [] Nothing+stepTypeOfSig FNullary = Nullary+stepTypeOfSig (FPartiallyLazy ss ms) = Lazy (length ss) noncomputing ms+ where noncomputing = findIndices needsCongruence ss++needsCongruence :: Strictness -> Bool+needsCongruence C.Lazy = False+needsCongruence C.Strict = True++hsid :: Name -> Doc+hsid = text . var2id++var2id [] = []+var2id ('-':cs) = '_' : var2id cs+var2id (c:cs) | isUpper c = toLower c : var2id cs+ | otherwise = c : var2id cs++generateArgs :: Int -> [MetaVar]+generateArgs max = foldr op [] [1..max]+ where op idx terms = ("arg" ++ show idx):terms++smart_cons_name nm = intercalate "_" (splitOn "-" nm) ++ "_"++-- function names+cType = "Type"+cComps = "ComputationType"+cValue = "FValue"+cFunconName = "FName"+cFunconApp = "FApp"+cTupleNot = "FTuple"+cListNot = "FList"+cMapNot = "FMap"+cSetNot = "FSet"+cStrictF = "StrictFuncon"+cStrict = "Strict"+cNonStrictF = "NonStrictFuncon"+cNonStrict = "NonStrict"+cPartialLazyF = "PartiallyStrictFuncon"+cNullaryF = "NullaryFuncon"+cTupleType = "Tuples"+cFVar = "TVar"+cFApp = "TApp"+cFName = "TName"+cFList = "TList"+cChar = "Char"+cFMap = "FMap"+cFSet = "FSet"+cTFuncon = "TFuncon"+cFSortUnion = "FSortUnion"+cFSortComputes = "FSortComputes"+cFSortComputesFrom = "FSortComputesFrom"+cString = "String"+cFloat = "Float"+cNat = "Nat"+cPValue = "PValue"+cPSeqVar = "PSeqVar"+cPMetaVar = "PMetaVar"+cPWildCard = "PWildCard"+cVPLit = "VPLit"+cVPWildCard = "VPWildCard"+cVPSeqVar = "VPSeqVar"+cPADT = "PADT"+cPList = "PList"+cPTuple = "PTuple"+cVPMetavar = "VPMetaVar"+cPAnnotated = "PAnnotated"+cVPAnnotated = "VPAnnotated"+cSCEquality = "SCEquality"+cSCInequality = "SCInequality"+cSCIsInSort = "SCIsInSort"+cSCNotInSort = "SCNotInSort"+cSCPatternMatch = "SCPatternMatch"+cSCPatternMismatch = "SCPatternMismatch"+cDefMutable = "DefMutable"+cDefInherited = "DefInherited"+cDefInput = "DefInput"+cDefOutput = "DefOutput"+cDefControl = "DefControl"+cFStarOp = "StarOp"+cFPlusOp = "PlusOp"+cFQuestionMarkOp = "QuestionMarkOp"+cADTVal = "ADTVal"+cADTType = "ADT"+cDataTypeMembers = "DataTypeMembers"+--TODO can we use show and read?+cDataTypeInclusion = "DataTypeInclusion"+cDataTypeConstructor = "DataTypeConstructor"++lifted_fSideCondition = "lifted_sideCondition"+fSideCondition = "sideCondition"+fSubsEval = "subsAndRewrite"+fliftfsMatch = "lifted_fsMatch" +fliftvsMatch = "lifted_vsMatch"+fliftvMatch = "lifted_vMatch" +fliftvMaybeMatch = "lifted_vMaybeMatch"+ffsMatch = "fsMatch"+fvsMatch = "vsMatch"+fvMatch = "vMatch"+fvMaybeMatch = "vMaybeMatch"+fRewritten = "rewritten"+fRewTo = "rewriteTo"+fRewTermTo = "rewriteTermTo"+fStepTo = "stepTo"+fStepTermTo = "stepTermTo"+fEvalRules = "evalRules"+fNorule = "norule"+fSortErr = "sortErr"+fApplyFuncon = "applyFuncon"+fCongruence = "congruence"+fAfterRewrite = "afterRewrite"+fFuncons= "funcons"+fEntities = "entities"+fTypes = "types"+fLibFromList = "libFromList"+ftypeEnvFromList = "typeEnvFromList"+fIsVal = "isVal"+fHasStep = "hasStep"+fpremise = "premise"+fgetDCTRLPatt = "getControlPatt"+fgetINHPatt = "getInhPatt"+fgetMUTPatt = "getMutPatt"+fputMUTTerm = "putMutTerm"+fWithINHTerm = "withInhTerm"+fWithCTRLTerm = "withControlTerm"+fraiseTerm = "raiseTerm"+fwriteOUTTerm = "writeOutTerm"+freceiveSignalPatt = "receiveSignalPatt"+freadOUTPatt = "readOutPatt"+fTypes_unval = "types_unval"+ffvalues = "map FValue"+fmatchInput = "matchInput"+frewriteType = "rewriteType"+fwithExactInput = "withExactInputTerms"+fwithExtraInput = "withExtraInputTerms"+fliftEnvStore = "lifted_envStore"+fliftEnvRewrite = "lifted_envRewrite"+fEnvStore = "envStore"+fEnvRewrite = "envRewrite"
+ src/Print/Util.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE LambdaCase #-}++module Print.Util where++import Types.SourceAbstractSyntax (SeqSortOp(..))+import Types.CoreAbstractSyntax++import Data.List (intersperse, intercalate)+import Data.List.Split+import Data.Char (toUpper)+import Data.Text (Text, unpack)+import Text.PrettyPrint.HughesPJ++import Funcons.EDSL (Funcons(..))++import System.FilePath (splitDirectories, dropFileName, dropExtension, takeBaseName)+++text' :: Text -> Doc+text' = text . unpack++gList :: [Doc] -> Doc+gList = brackets . hcat . punctuate comma++gTuple :: [Doc] -> Doc+gTuple = parens . hcat . punctuate comma++gAngle :: [Doc] -> Doc+gAngle = angles . hcat . punctuate comma+ where angles d = text "<" <> d <> text ">"++gString :: String -> Doc+gString = doubleQuotes . text++ppSortOp :: SeqSortOp -> Doc+ppSortOp PlusOp = text "+"+ppSortOp StarOp = text "*"+ppSortOp QuestionMarkOp = text "?"++gMaybe :: Maybe Doc -> Doc+gMaybe Nothing = text cNothing+gMaybe (Just d) = text cJust <+> parens d+cNothing = "Nothing"+cJust = "Just"++camelcase :: String -> String+camelcase str = concatMap firstToCap (splitOneOf " -" str)+ where firstToCap [] = []+ firstToCap (hd:tl) = (toUpper hd):tl++dropUntil :: (a -> Bool) -> [a] -> [a]+dropUntil prop xs = + case dropWhile prop xs of+ [] -> xs + xs' -> dropUntil prop (tail xs')++replace :: String -> String -> String -> String+replace f t orig = intercalate t (splitOn f orig)++infixl 6 <.>+infixl 6 <$>+infixl 6 <=>+infixl 6 <->>+infixl 6 <<->+d1 <$> d2 = d1 <+> parens d2+d1 <=> d2 = d1 <+> text "=" <+> d2+d1 <->> d2 = d1 <+> text "->" <+> d2+d1 <<-> d2 = d1 <+> text "<-" <+> d2+(<.>) :: Doc -> Doc -> Doc+d1 <.> d2 = d1 <> text "." <> d2+vsep = vcat . intersperse (text "")++{-+termHasVar :: FTerm -> Bool+termHasVar = \case+ TVar _ -> True+ TName nm -> False+ TApp nm term -> any termHasVar term+ TSeq terms -> any termHasVar terms+ TSet terms -> any termHasVar terms+ TMap terms -> any termHasVar terms+ TList terms -> any termHasVar terms+ TFuncon f -> False+ TSortSeq term op -> termHasVar term+ TSortUnion ty1 ty2 -> termHasVar ty1 || termHasVar ty2+ TSortInter ty1 ty2 -> termHasVar ty1 || termHasVar ty2+ TSortComplement ty -> termHasVar ty+ TSortComputes term -> termHasVar term+ TSortComputesFrom from to -> termHasVar from || termHasVar to + TAny -> False++staticSubstitute :: FTerm -> Funcons+staticSubstitute = \case+ TVar "_" -> FValue VAny+ TVar var -> error ("failed to apply static substitution to: " ++ var)+ TName nm -> FName nm+ TApp nm term -> FApp nm (map staticSubstitute term)+-- TSeq terms -> map staticSubstitute terms+ TSet terms -> FSet (map staticSubstitute terms)+ TMap terms -> FMap (map staticSubstitute terms)+ TList terms -> FList (map staticSubstitute terms)+ TFuncon f -> f+ TSortSeq term op -> FSortSeq (staticSubstitute term) op+ TSortUnion ty1 ty2 -> FSortUnion (staticSubstitute ty1) (staticSubstitute ty2)+ TSortInter ty1 ty2 -> FSortInter (staticSubstitute ty1) (staticSubstitute ty2)+ TSortComplement ty -> FSortComplement (staticSubstitute ty)+ TSortComputes term -> FSortComputes (staticSubstitute term)+ TSortComputesFrom from to -> FSortComputesFrom (staticSubstitute from)+ (staticSubstitute to)+ TAny -> FValue VAny+-}++funcons2FTerm :: Funcons -> FTerm+funcons2FTerm = \case+ FName nm -> TName nm+ FApp nm term -> TApp nm (map funcons2FTerm term)+-- FTuple terms -> TTuple (map funcons2FTerm terms)+ FSet terms -> TSet (map funcons2FTerm terms)+ FMap terms -> TMap (map funcons2FTerm terms)+ FBinding t1 t2 -> TBinding (funcons2FTerm t1) (TSeq (map funcons2FTerm t2))+-- FList terms -> TList (map funcons2FTerm terms)+ FSortSeq term op -> TSortSeq (funcons2FTerm term) op+ FSortUnion ty1 ty2 -> TSortUnion (funcons2FTerm ty1) (funcons2FTerm ty2)+ FSortInter ty1 ty2 -> TSortInter (funcons2FTerm ty1) (funcons2FTerm ty2)+ FSortComplement ty -> TSortComplement (funcons2FTerm ty)+ FSortComputes term -> TSortComputes (funcons2FTerm term)+ FSortComputesFrom from to -> TSortComputesFrom (funcons2FTerm from)+ (funcons2FTerm to)+ FValue v -> TFuncon (FValue v)+ FSortPower ty1 ty2 -> TSortPower (funcons2FTerm ty1) (funcons2FTerm ty2)++hsmodNameFromPath :: String -> FilePath -> [String]+hsmodNameFromPath lang file = hs_file_dir_as_list ++ [hs_file_name] + where hs_file_name = camelcase (takeBaseName file)+ hs_file_dir_as_list =+ (["Funcons", camelcase lang] ++) $+ map camelcase $ + dropUntil (not . (\x -> x `elem` roots)) $ + splitDirectories $+ dropFileName $ + dropExtension file+ roots = ["Funcons", "Funcons-beta", lang]
+ src/Simplify/ConcreteToAbstract.hs view
@@ -0,0 +1,364 @@+{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, TupleSections #-}+{-# LANGUAGE LambdaCase #-}++module Simplify.ConcreteToAbstract + (cs2as) where++import Types.ConcreteSyntax+import qualified Types.SourceAbstractSyntax as S++import CCO.Component+import CCO.Feedback+import CCO.Printing++import Control.Applicative+import Control.Monad.Except++import Data.Either (rights)+import Data.Foldable (foldrM)+import qualified Data.Map as M++instance MonadError String Feedback where+ throwError = errorMessage . wrapped++cs2as :: Bool -> Component CBSFile S.CBSFile +cs2as gen_ph = component (sFile gen_ph)++sFile :: MonadError String m => Bool -> CBSFile -> m S.CBSFile+sFile gen_ph file = toFile =<< sFilterSpecs gen_ph Nothing file+ where toFile (als, vardecls, specs) = do+ vts <- forM vardecls $ \decl -> case decl of + VarDeclSubType x t -> (:[]) . (x,) . S.SubTyOf <$> sSort t+ VarDeclType x t -> (:[]) . (x,) . S.ElemOf <$> sSort t+ return (S.CBSFile specs (M.fromList (concat vts)) (M.fromListWith (++) als))++sFilterSpecs :: MonadError String m => + Bool -> (Maybe [CommentPart]) -> [CBSSpec] + -> m ([(Name, [Name])], [VarDecl], [S.CBSSpec])+sFilterSpecs _ _ [] = return ([], [], [])+sFilterSpecs gen_ph mdoc (f@(FunconSpec _ _ _ _):c@(CommentSpec _):r@(RuleSpec _):rest)+ = sFilterSpecs gen_ph mdoc (c:f:r:rest)+sFilterSpecs gen_ph mdoc (spec:specs) = case spec of + -- completely ignore entity declarations (CBS-beta)+ EntitySpec _ -> sFilterSpecs gen_ph Nothing specs+ FunconSpec _ _ _ (Just (DefRewrite TermDots)) | not gen_ph -> + sFilterSpecs gen_ph Nothing specs + FunconSpec nm _ _ _ -> + let (relatedspecs, otherspecs') = span isRelated specs+ otherspecs = aliases ++ otherspecs'+ (aliases, rulespecs) = foldr op ([], []) relatedspecs+ where op a@(AliasSpec _ _) (as,rs) = (a:as,rs)+ op r@(RuleSpec _) (as,rs) = (as,r:rs)+ op _ acc = acc+ isRelated (AliasSpec _ _) = True+ isRelated (CommentSpec _) = True+ isRelated spec = isFunconRuleSpec spec + isFunconRuleSpec (RuleSpec r) = case r of + Inference _ conc -> nm == termName (concSource conc)+ _ -> False+ isFunconRuleSpec _ = False+ in do spec <- sSpec spec mdoc (map (\(RuleSpec r) -> r) rulespecs)+ (als,decls,specs) <- sFilterSpecs gen_ph Nothing otherspecs+ return (als, decls, spec:specs)+ CommentSpec parts -> case specs of+ ((FunconSpec _ _ _ _):otherspecs) -> sFilterSpecs gen_ph Nothing specs+ otherspecs -> sFilterSpecs gen_ph Nothing specs+ TypeSpec _ _ _ (Just (DefRewrite TermDots)) + | not gen_ph -> sFilterSpecs gen_ph Nothing specs+ LexisSpec _ -> sFilterSpecs gen_ph Nothing specs+ SyntaxSpec _ -> sFilterSpecs gen_ph Nothing specs+ SemanticsSpec _ _ _ _ _ _ -> sFilterSpecs gen_ph Nothing specs+ RuleSpec _ -> sFilterSpecs gen_ph Nothing specs+ OtherwiseSpec _ -> sFilterSpecs gen_ph Nothing specs+ AliasSpec t f -> do (als, decls, specs) <- sFilterSpecs gen_ph Nothing specs + return ((f,[t]):als,decls,specs)+ MetaVariablesSpec ds -> do (als, decls, specs) <- sFilterSpecs gen_ph Nothing specs + return (als, ds++decls,specs) + _ -> do spec <- sSpec spec mdoc []+ (als, decls, specs) <- sFilterSpecs gen_ph Nothing specs+ return (als, decls, (spec:specs))++sSpec :: MonadError String m => CBSSpec -> (Maybe [CommentPart]) -> [Rule] -> m S.CBSSpec+sSpec spec mdoc rules = case spec of+ MetaSpec s -> return (S.MetaSpec s)+ Auxiliary s -> sSpec s mdoc rules+ FunconSpec nm mparams ty mcs -> do+ sig <- buildFSig nm mparams ty mdoc+ case mcs of+ Just (DefRewrite term) -> S.FunconSpec . S.FAbbrv sig <$> sMaybeTerm term+ _ -> S.FunconSpec . S.FRules sig <$> sRules rules+ TypeSpec nm mparams _ Nothing -> S.TypeSpec <$> decl+ where decl = S.DataTypeDecl nm <$> params <*> return []+ params = maybe (return []) (mapM sValParam) mparams+ TypeSpec nm mparams _ tcs -> (S.TypeSynonymSpec <$>) $ case tcs of+ Just (DefRewrite ty) -> S.TypeSynonymDecl nm <$> params <*> sSort ty+ where params = maybe (return []) (mapM sValParam) mparams+ _ -> throwError ("unexpected type synonym: " ++ nm)+ DatatypeSpec nm mparams mbound alts -> S.DataTypeSpec <$> decl+ where decl = S.DataTypeDecl nm <$> params <*> sAlts alts + params = maybe (return []) (mapM sValParam) mparams+ sAlts = mapM sAlt+ sAlt alt = case alt of + Inj _ ty -> S.DataTypeInclusion <$> sSort ty+ Cons nm mparams -> S.DataTypeConstructor nm <$> mapM sSortOfParam params+ where params = maybe [] id mparams+ AltDots -> throwError "undefined datatype alternative"+ _ -> throwError "unexpected lexis/syntax/semantics specification"++sSortOfParam :: MonadError String m => Param -> m S.FSort +sSortOfParam p = case p of+ Param _ (Just (InType ty)) -> sSort ty+ Param _ (Just (Sup ty)) -> sSort ty+ _ -> throwError ("unexpected type parameter: " ++ show p)++sValParam :: MonadError String m => Param -> m S.FParam+sValParam (Param var mbound) = case mbound of+ Nothing -> return (mkVar var, Nothing)+ Just bound -> case bound of+ Sub ty -> (mkVar var,) . Just <$> bValSort ty+ Sup ty -> (mkVar var,) . Just <$> bValSort (NameApp "nullabe" (TermName "values"))+ InType ty -> (mkVar var,) . Just <$> bValSort ty+ where mkVar var = case var of + Nothing -> S.PPAny+ Just str -> case last str of+ '*' -> S.PPSeqMetaVar str S.StarOp+ '?' -> S.PPSeqMetaVar str S.QuestionMarkOp+ '+' -> S.PPSeqMetaVar str S.PlusOp+ _ -> S.PPMetaVar str++buildFSig :: MonadError String m => + Name -> Maybe Params -> Term -> Maybe [CommentPart] -> m S.FSig+buildFSig nm mparams ty mdoc = do+ params <- maybe (return []) (mapM sValParam) mparams+ S.FSig nm params <$> bValSort ty <*> sMDoc mdoc++sMDoc :: MonadError String m => Maybe [CommentPart] -> m (Maybe [S.CommentPart])+sMDoc Nothing = return Nothing+sMDoc (Just cs) = Just <$> mapM sCommentPart cs++sCommentPart :: MonadError String m => CommentPart -> m S.CommentPart+sCommentPart (Ordinary o) = return $ S.Ordinary o+sCommentPart (Asterisk) = return $ S.Asterisk+sCommentPart (At s) = return $ S.At s+sCommentPart (CommentTerm t) = return $ S.CommentTerm t+sCommentPart (CommentPremise f) = return $ S.CommentPremise f+sCommentPart (SpecInComment spec) = S.SpecInComment <$> sSpec spec Nothing []++bValSort :: MonadError String m => Type -> m S.FSort+bValSort ty = case ty of + TermTuple [t2] -> bValSort t2+ _ -> sTerm ty++sMaybeTerm :: MonadError String m => Term -> m (Maybe S.FTerm)+sMaybeTerm TermDots = return Nothing+sMaybeTerm t = Just <$> sTerm t++sTerm :: MonadError String m => Term -> m S.FTerm+sTerm t = case t of+ TermDots -> return (S.TTuple [])+ TermVar Nothing -> return $ S.TAny+ TermVar (Just var) -> return $ S.TMetaVar var+ TermConst cnst -> case cnst of+ ConstAtom a -> return $ S.TLiteral (S.FLiteralString a)+ ConstString str -> return $ S.TLiteral (S.FLiteralString str)+ ConstNat n -> return $ S.TLiteral (S.FLiteralNat n)+ ConstFloat f -> throwError "CBS compiler does not support float constants"+ TermName nm -> return $ S.TName nm+ VarApp var term -> throwError ("CBS compiler does not support variable application: " ++ show var)+ NameApp nm (TermTuple terms) + -> S.TApp nm <$> mapM sTerm terms+ NameApp nm term -> S.TApp nm . (:[]) <$> sTerm term+ Typed term ty -> sTerm term --throwError ("unexpected typed term: " ++ show (term,ty))+ Computes ty -> S.TSortComputes <$> sTerm ty+ ComputesFrom f t -> S.TSortComputesFrom <$> sTerm f <*> sTerm t+ TermPostfix t op -> flip S.TSortSeq op <$> sTerm t + TermSequence ts -> throwError "top-level term-sequence" + TermTuple ts -> S.TTuple <$> mapM sTerm ts+ TermList ts -> S.TList <$> mapM sTerm ts+ TermSet ts -> S.TSet <$> mapM sTerm ts+ TermMap ps -> S.TMap <$> mapM sPoint ps+ where sPoint Nothing = throwError "... in map literal"+ sPoint (Just (f,t)) = S.TBinding <$> sTerm f <*> sTerm t+ TermUnion t1 t2 -> S.TSortUnion <$> sTerm t1 <*> sTerm t2+ TermInter t1 t2 -> S.TSortInter <$> sTerm t1 <*> sTerm t2+ TermPower t1 t2 -> S.TSortPower <$> sTerm t1 <*> sTerm t2+ TermComplement ty -> S.TSortComplement <$> sTerm ty+ + SemanticsApp _ _ _ -> throwError "unexpected semantic application in term"+ +sRules :: MonadError String m => [Rule] -> m [S.FRule]+sRules = mapM sRule++sRule :: MonadError String m => Rule -> m S.FRule+sRule r = case r of+ Inference _ (ConcStatic _ _ _ _ _) -> throwError "missing translation for static rules"+ Inference _ (ConcTyping _ _ _) -> throwError "missing translation for typing rules"+ Desugar _ _ _ -> error "translating desugar rule"+ Semantics _ _ _ _ -> error "translation semantics rule"+ Inference scs (ConcRewrite t1 t2) -> rewriteRule t1 t2 scs+ Inference scs (ConcDynamic mc st1 arr st2) -> stepRule mc st1 st2 arr scs + where nmOfTerm t = case t of+ TermName nm -> return nm+ NameApp nm _ -> return nm+ _ -> throwError ("invalid rule pattern: " ++ show t)+ patsOf t = case t of+ TermName nm -> return Nothing+ NameApp _ (TermTuple []) -> return Nothing+ NameApp _ term -> Just <$> term2pats term+ _ -> throwError ("invalid rule pattern: " ++ show t)++ rewriteRule :: MonadError String m => + Term -> Term -> [Premise] -> m S.FRule+ rewriteRule t1 t2 scs = do+ S.FRuleRewrite (termName t1) + <$> case termArgs t1 of + Nothing -> return Nothing+ Just args -> Just <$> mapM term2pat args+ <*> fmap Just (sTerm t2)+ <*> prem2sideconds scs++ stepRule :: MonadError String m => + (Maybe Context) -> State -> State -> Dynamic -> [Premise] -> m S.FRule+ stepRule mc s1 s2 arr prs = do+ source <- case termArgs (stateTerm s1) of+ Nothing -> return Nothing+ Just args -> Just <$> mapM term2pat args+ target <- sTerm (stateTerm s2)+ inhs <- sEntities term2pats (contextEnts mc)+ muts_in <- sEntities term2pat (stateEnts s1)+ muts_out <- sEntities sTerm (stateEnts s2)+ (inps, outs, ctrs) <- foldrM arrowEnts ([], [], []) (dynamicEnts arr)+ let fstep = S.FStep source target inhs (muts_in, muts_out) inps outs ctrs+ S.FRuleStep (termName t1) fstep <$> prem2conds prs+ where t1 = stateTerm s1+ muts_in = stateEnts s1+ t2 = stateTerm s2+ muts_out = stateEnts s2+ arrowEnts (n,t,pol) (is, os, cs) = case pol of+ Nothing -> (\t' -> (is,os,(n,t'):cs)) <$> term2pat t+ Just In -> (\t' -> ((n,t'):is,os,cs)) <$> term2pat t+ Just Out -> (\t' -> (is,(n,t'):os,cs)) <$> sTerm t+{-+ mpats <- patsOf t1+ target <- sTerm t2+ context <- sMaybeContext term2pat mc+ muts_pat <- sMutEntities term2pat muts_in+ muts_term <- sMutEntities sTerm muts_out+ (ins, outs, sigs) <- sArrow term2pat sTerm term2pat arr+ let step = S.FStep mpats target context (muts_pat, muts_term) ins outs sigs + nm <- nmOfTerm t1+ antecedents <- forms2prems scs+ return (S.FRuleStep nm step antecedents)+-}++term2pats :: MonadError String m => Term -> m [S.FPattern]+term2pats term = case term of+ TermSequence ts -> terms2pats ts+ TermTuple ts -> terms2pats ts + _ -> (:[]) <$> term2pat term ++terms2pats :: MonadError String m => [Term] -> m [S.FPattern]+terms2pats = mapM term2pat++term2pat :: MonadError String m => Term -> m S.FPattern+term2pat t = case t of+ TermConst cnst -> case cnst of+ ConstAtom str -> return $ S.PLit (S.FLiteralAtom str)+ ConstString str -> return $ S.PLit (S.FLiteralString str)+ ConstNat n -> return $ S.PLit (S.FLiteralNat n)+ ConstFloat f -> return $ S.PLit (S.FLiteralFloat f)+ TermVar (Just var) + | last var == '*' -> return $ S.PSeqMetaVar var S.StarOp+ | last var == '+' -> return $ S.PSeqMetaVar var S.PlusOp+ | last var == '?' -> return $ S.PSeqMetaVar var S.QuestionMarkOp+ | otherwise -> return $ S.PMetaVar var+ TermVar Nothing -> return $ S.PAny+ TermDots -> return $ S.PAny+ TermName nm -> return $ S.PADT nm []+ NameApp nm term -> S.PADT nm <$> term2pats term+ VarApp var term -> throwError "variable application not allowed in a pattern"+ Typed term ty -> S.PAnnotated <$> term2pat term <*> sSort ty+ Computes _ -> throwError " =>_ appearing in pattern"+ ComputesFrom _ _ -> throwError " _=>_ appearing in pattern"+ TermPostfix (TermVar Nothing) op -> return $ S.PSeqMetaVar "___" op + TermPostfix TermDots op -> return $ S.PSeqMetaVar "___" op+ TermPostfix _ _ -> throwError "postfix in pattern"+ TermSequence ts -> throwError "top-level term-sequence in pattern" + TermUnion _ _ -> throwError "sort-union in pattern"+ TermInter _ _ -> throwError "sort-intersect in pattern"+ TermComplement _ -> throwError "sort-complement in pattern"+ TermTuple ts -> S.PSeq <$> terms2pats ts+ TermList ts -> S.PList <$> terms2pats ts+ TermSet ts -> throwError "set notation in pattern" + TermMap ts -> throwError "map notation in pattern"+ TermPower t1 t2 -> throwError "term power in pattern"+ SemanticsApp _ _ _-> throwError "unexpected semantic application in pattern"++prem2sideconds :: MonadError String m => [Premise] -> m [S.FSideCondition]+prem2sideconds prems = concat <$> mapM filterOp prems+ where filterOp prem = rights <$> prem2cond prem++prem2conds :: MonadError String m => [Premise] -> m [Either S.FPremiseStep S.FSideCondition]+prem2conds prems = concat <$> mapM prem2cond prems++prem2cond :: MonadError String m => Premise -> m [Either S.FPremiseStep S.FSideCondition]+prem2cond prem = case prem of + PremStatic _ _ _ _ _ -> + throwError "missing translation for static premises"+ PremTyping (Just _) _ _ -> + throwError "missing translation for typing premises"+ PremTyping _ (StateExplicit _ _) _ -> + throwError "missing translation for typing premises"+ PremDynamic mc st1 arr st2 -> + (:[]) . Left <$> bPremiseStep mc st1 arr st2 + PremRewrite t1 t2 -> + (((:[]) . Right) .) . S.SCPatternMatch <$> sTerm t1 <*> term2pats t2+ PremEquality t1 t2 -> + (((:[]) . Right) .) . S.SCEquality <$> sTerm t1 <*> sTerm t2+ PremInequality t1 t2 -> + (((:[]) . Right) .) . S.SCInequality <$> sTerm t1 <*> sTerm t2+ PremTyping Nothing (StateImplicit t1) t2 -> + (((:[]) . Right) .) . S.SCIsInSort <$> sTerm t1 <*> sSort t2+ PremSubtype t1 t2 -> + return []++bPremiseStep :: MonadError String m => + Maybe Context -> State -> Dynamic -> State -> m S.FPremiseStep+bPremiseStep mc lhs arr rhs = do + source <- sTerm (stateTerm lhs)+ target <- term2pats (stateTerm rhs)+ inhs <- sEntities sTerm (contextEnts mc)+ muts_in <- sEntities sTerm (stateEnts lhs)+ muts_out <- sEntities term2pat (stateEnts rhs)+ (inps,outs,ctrs) <- foldrM op ([],[],[]) (dynamicEnts arr)+ return (S.FPremiseStep source target inhs (muts_in,muts_out) inps outs ctrs)+ where op (n,t,pol) (is, os, cs) = case pol of+ Nothing -> (\t' -> (is,os,(n,t'):cs)) <$> term2pat t+ Just In -> (\t' -> ((n,t'):is,os,cs)) <$> sTerm t+ Just Out -> (\t' -> (is,(n,t'):os,cs)) <$> term2pat t++sEntities :: MonadError String m => (Term -> m a) -> [EntTerm] -> m [(Name, a)]+sEntities simplifier = mapM op+ where op (nm, t) = (nm,) <$> simplifier t+{-+sArrow :: MonadError String m => + (Term -> m ins) -> (Term -> m outs) -> (Term -> m sigs) -> + Arrow -> m ([(Name, ins)],[(Name, outs)],[(Name, sigs)])+sArrow sIns sOuts sSigs arr = case arr of+ Normal es -> mkEntities es+ Static es -> mkEntities es+ Rewrite -> mkEntities []+ where mkEntities = foldM op ([],[],[]) + where op (ins,outs,sigs) (EmitIn nm term) = do+ s <- sIns term+ return ((nm,s):ins,outs,sigs)+ op (ins,outs,sigs) (EmitOut nm term) = do+ s <- sOuts term+ return (ins,(nm,s):outs,sigs)+ op (ins,outs,sigs) (EmitSig nm term) = do+ s <- sSigs term+ return (ins,outs,(nm,s):sigs)+-}+sSort :: MonadError String m => Term -> m S.FSort+sSort = sTerm+
+ src/Simplify/CoreToTarget.hs view
@@ -0,0 +1,174 @@+{-# Language FlexibleContexts, ScopedTypeVariables, LambdaCase, MultiParamTypeClasses, TupleSections, FlexibleInstances, OverloadedStrings #-}++-- | +-- Sanity checking and simplifications regarding:+--+-- * input entities+module Simplify.CoreToTarget where++import CCO.Component (Component, component)+import CCO.Feedback (Feedback, errorMessage)+import CCO.Printing (wrapped)++import Control.Applicative+import Control.Arrow ((***))+import Control.Monad.Except++import Simplify.Utils++import Data.Either (lefts)+import Data.Maybe (catMaybes)+import Data.Text (pack)+++--------------------------------------------------------------------++import Funcons.EDSL (FTerm(TVar), string_, HasTypeVar(..), limitedSubsTypeVarWildcard, showOp, SeqSortOp(..))++import Types.SourceAbstractSyntax (Name, MetaVar)+import Types.Bindings(HasPatVar(..))+import Types.CoreAbstractSyntax++import qualified Types.TargetAbstractSyntax as T++--------------------------------------------------------------------++-- require for forming a pipeline with uu-cco library+core2target :: Component CBSFile T.CBSFile+core2target = component simplifyCBSFile++instance MonadError String Feedback where+ throwError = errorMessage . wrapped++--------------------------------------------------------------------++simplifyCBSFile :: MonadError String m => CBSFile -> m T.CBSFile+simplifyCBSFile (CBSFile file env als) = + T.CBSFile <$> (concat <$> mapM (simplifySpecs env) file) + <*> return env <*> return als++simplifySpecs :: MonadError String m => TypeEnv -> CBSSpec -> m [T.CBSSpec]+simplifySpecs env (FunconSpec fspec) = return . T.FunconSpec <$> simplifyFSpec env fspec+simplifySpecs env (DataTypeSpec spec) = return [T.DataTypeSpec spec]+simplifySpecs env (EntitySpec spec) = return [T.EntitySpec spec]+simplifySpecs env (MetaSpec spec) = return [T.MetaSpec spec]+simplifySpecs env (ConsSpec spec) = + return (T.FunconSpec (simplifyConsSpec spec) : [T.ConsSpec spec])++--------------------------------------------------------------------++simplifyConsSpec :: ConsSpec -> T.FunconSpec+simplifyConsSpec (ValCons nm (TypeCons ss) pattypes _ _) = + genValConsFuncons nm ss "non-strict-datatype-value" pattypes+simplifyConsSpec (ValCons nm sig pattypes _ _) = + genValConsFuncons nm sig "datatype-value" pattypes+ where sig = if null pattypes then FNullary else FStrict++genValConsFuncons nm sig cons pattypes = + T.FRules nm sig Nothing [rule] []+ where rule = T.FRewriteRule pats (Just (TApp cons (cname:args))) scds+ cname = TFuncon (string_ nm) + args = map (TVar . fst) vars+ pats = zipWith mkPat vars pattypes+ -- sorts are ignored (no substitution available)+ where mkPat (var, mop) sort = msvar + where msvar = case mop of Nothing -> PMetaVar var+ Just op -> PSeqVar var op+-- sides = zipWith mkSide vars pattypes+-- where mkSide (var,mop) sort = SCIsInSort (TVar var) sort + vars = zipWith mkOp [1..] pattypes+ where mkOp i pat = case pat of + TSortSeq _ op -> var $ Just op+ TSortPower _ _ -> var $ Just StarOp+ TVar str -> case last str of+ '*' -> var $ Just StarOp+ '?' -> var $ Just QuestionMarkOp+ '+' -> var $ Just PlusOp+ _ -> var Nothing+ _ -> var Nothing+ where var mop = ("_X" ++ show i ++ maybe "" showOp mop, mop)+ scds = case sig of FStrict -> map (uncurry toVal) vars+ where toVal x mop = case mop of+ Just op -> SCIsInSort (TVar x) (TSortSeq (TSortSeq (TName "values") QuestionMarkOp) op) + Nothing -> SCIsInSort (TVar x) (TSortSeq (TName "values") QuestionMarkOp)+ _ -> []++simplifyFSpec :: MonadError String m => TypeEnv -> FunconSpec -> m T.FunconSpec+simplifyFSpec env (FRules nm sig mdoc rews steps) =+ T.FRules nm sig mdoc <$> mapM (simplifyRewrite env) rews + <*> mapM (simplifyFStepRule env) steps++simplifyRewrite :: MonadError String m => TypeEnv -> FRewriteRule -> m T.FRewriteRule+simplifyRewrite env rule@(FRewriteRule pats rhs conds) = -- TODO why do we need a different FRewriteRule datatype?+ return (limitedSubsTypeVarWildcard (pvars rule) (Just (TSortSeq (TName "values") QuestionMarkOp)) env $ T.FRewriteRule pats rhs conds)++simplifyFStepRule :: MonadError String m => TypeEnv -> FStepRule -> m T.FStepRule+simplifyFStepRule env rule@(FStepRule step pcs) =+ do b <- checkInputRouting step (lefts pcs)+ guardM b "Unsupported routing between input entities."+ limitedSubsTypeVarWildcard (pvars rule) (Just (TSortSeq (TName "values") QuestionMarkOp)) env <$> + (T.FStepRule <$> simplifyFStep step <*> mapM (traverseEither simplifyFPremiseStep return) pcs)++--------------------------------------------------------------------++{-+simplifyF2TPattern :: MonadError String m => FPattern -> m T.TPattern+simplifyF2TPattern p = case p of+ PTuple ps -> T.TPADT "tuples" <$> mapM simplifyF2TPattern ps + PList [p] -> T.TPADT "lists" . (:[]) <$> simplifyF2TPattern p+ PList ps -> throwError "cannot simplify list-notation to type-pattern"+ PAnnotated pat s -> simplifyF2TPattern pat+ PADT cons ps -> T.TPADT (pack cons) <$> mapM simplifyF2TPattern ps+ PAny -> return $ T.TPWildCard+ PLit lit -> return $ T.TPLit (TFuncon $ simplifyLiteral lit)+ PMetaVar var -> return $ T.TPVar var + PSeqMetaVar var op -> return $ T.TPSeqVar var op+-}++simplifyFStep :: MonadError String m => FStep -> m T.FStep+simplifyFStep st =+ return $ T.FStep+ { T.stepSource = stepSource st+ , T.stepTarget = stepTarget st+ , T.stepInheritedEntities = stepInheritedEntities st+ , T.stepMutableEntities = stepMutableEntities st+ , T.stepInputEntities = map (\(n,ps,_) -> (n,ps)) + (stepInputEntities st)+ , T.stepOutputEntities = stepOutputEntities st+ , T.stepControlEntities = stepControlEntities st+ }++simplifyInputEntity :: MonadError String m => (Name,[FPattern],[MetaVar]) -> m (Name,[MetaVar])+simplifyInputEntity (n,ps,_) = (n,) <$> mapM patToMV ps+ where+ patToMV (PMetaVar mv) = return mv+ patToMV _ = throwError "Currently we only allow meta-variables in input patterns." -- TODO: could also allow underscores++simplifyFPremiseStep :: MonadError String m => FPremiseStep -> m T.FPremiseStep+simplifyFPremiseStep pst =+ return $ T.FPremiseStep+ { T.premiseSource = premiseSource pst+ , T.premiseTarget = premiseTarget pst+ , T.premiseInheritedEntities = premiseInheritedEntities pst+ , T.premiseMutableEntities = premiseMutableEntities pst+ , T.premiseInputEntities = map simplifyInputEntityPremise (premiseInputEntities pst)+ , T.premiseOutputEntities = premiseOutputEntities pst+ , T.premiseControlEntities = premiseControlEntities pst+ }++simplifyInputEntityPremise :: (Name,[FTerm],Maybe MetaVar) -> (Name,[FTerm],T.InputAccess)+simplifyInputEntityPremise (n,ts,Nothing) = (n,ts,T.ExactInput)+simplifyInputEntityPremise (n,ts,Just _) = (n,ts,T.ExtraInput)++--------------------------------------------------------------------++checkInputRouting :: forall m. MonadError String m => FStep -> [FPremiseStep] -> m Bool+checkInputRouting step psteps =+ and <$> mapM (\(n,_,mvs) -> (mvs ==) <$> catMaybes <$> mapM (premiseMv n) psteps) (stepInputEntities step)+ where+ premiseMv :: Name -> FPremiseStep -> m (Maybe MetaVar)+ premiseMv n pstep = case lookup2 n (premiseInputEntities pstep) of+ Nothing -> throwError "Mismatched input entity in rule" -- do we check this earlier?+ Just (_,mmv) -> return mmv++--------------------------------------------------------------------
+ src/Simplify/LiftStrictness.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE OverloadedStrings #-}++module Simplify.LiftStrictness where++import Types.SourceAbstractSyntax (SeqSortOp(..))+import Types.CoreAbstractSyntax (FSig(..), FTerm(..), FPattern (..)+ ,Strictness(..),FSideCondition(..))+import Types.TargetAbstractSyntax hiding (FPattern(..))++import Data.Text (pack)+import CCO.Component++lift_strictness :: Component CBSFile CBSFile+lift_strictness = component (return . lCBSFile)++lCBSFile :: CBSFile -> CBSFile+lCBSFile cbsf = doToFuncons lFSpec cbsf++lFSpec :: FunconSpec -> FunconSpec+lFSpec spec@(FRules nm sig mcs rs ss) = case sig of + FLazy -> spec+ FNullary -> spec+ FStrict -> FRules nm FLazy mcs rs ss'+ where ss' = steprule : ss+ steprule = FStepRule step [Left premise]+ step = FStep [PAnnotated (PSeqVar "V*" StarOp) + (TSortSeq (TSortSeq (TName "values") QuestionMarkOp) StarOp)+ ,PMetaVar "X"+ ,PSeqVar "Y*" StarOp]+ (TApp (pack nm) [TVar "V*", TVar "X'", TVar "Y*"])+ [] [] [] [] []+ premise = FPremiseStep (TVar "X") [PMetaVar "X'"] [] [] [] [] []+{- moved to TargetToIML+ rewrule = FRewriteRule [PSeqVar "X*" StarOp] + (Just (TApp (pack nm) [TVar "Y*"])) [cond]+ where cond = SCPatternMatch (TVar "X*") (PSeqVar "Y*" StarOp) -}+ FPartiallyLazy ann mseqvar -> FRules nm FLazy mcs rs ss'+ where ss' = map mkRule ruleKeys ++ seqvarRule ++ ss+ ruleKeys = map fst $ filter ((Strict ==) . snd) keys+ keys = zip [1..] ann+ seqvarRule = case mseqvar of + Nothing -> []+ Just sann -> [] --[rule] -- TODO similar to strict case but taking annotation into account++ mkRule k = FStepRule step [Left premise] + where step = FStep pats (TApp (pack nm) terms) [] [] [] [] [] + (pats,terms) = foldr op base keys+ where base = case mseqvar of + Just _ -> ([PSeqVar "X*" StarOp]+ ,[TVar "X*"]) + _ -> ([], [])+ op (k',sness) (pats, terms) + | k' == k = (PMetaVar var:pats+ ,TVar (var ++ "'") : terms) + | k' < k, Strict <- sness = + (PAnnotated (PMetaVar var) + (TSortSeq (TName "values") QuestionMarkOp):pats+ ,TVar var : terms)+ | True = (PMetaVar var : pats, TVar var : terms)+ where var = "X" ++ show k'+ premise = FPremiseStep (TVar var) [PMetaVar (var ++ "'")] + [] [] [] [] []+ where var = "X" ++ show k
+ src/Simplify/Simplifier.hs view
@@ -0,0 +1,460 @@+{-# Language FlexibleContexts, LambdaCase, MultiParamTypeClasses, TupleSections, FlexibleInstances, OverloadedStrings #-}++module Simplify.Simplifier where++import Funcons.EDSL (Values(..), Funcons(..), string__)+import qualified Funcons.EDSL as EDSL++import CCO.Component (Component, component)+import CCO.Feedback (Feedback, errorMessage)+import CCO.Printing (wrapped)++import Control.Applicative+import Control.Monad.Except++import Data.Either+import Data.Monoid+import Data.Text (pack)+import qualified Data.Map as M+import qualified Data.Set as S ++import Simplify.Utils++--------------------------------------------------------------------++import Types.Bindings+import Types.SourceAbstractSyntax+import qualified Types.CoreAbstractSyntax as C++--------------------------------------------------------------------++-- require for forming a pipeline with uu-cco library+simplifier :: Component CBSFile C.CBSFile+simplifier = component simplifyCBSFile++instance MonadError String Feedback where+ throwError = errorMessage . wrapped++--------------------------------------------------------------------++simplifyCBSFile :: MonadError String m => CBSFile -> m C.CBSFile+simplifyCBSFile (CBSFile file env als) = do+ env' <- simplifyTypeEnv env + let kindMap = foldr bindTypeDecl M.empty file+ specss <- mapM (simplifyCBSSpec kindMap env') file + let specs = map (mvarConditions env') (concat specss)+ return $ C.CBSFile specs env' als++bindTypeDecl :: CBSSpec -> KindMap -> KindMap+bindTypeDecl (TypeSpec (DataTypeDecl nm _ _)) = M.insert nm Type+bindTypeDecl (DataTypeSpec (DataTypeDecl nm _ _)) = M.insert nm DataType +bindTypeDecl _ = id++mvarConditions :: C.TypeEnv -> C.CBSSpec -> C.CBSSpec+mvarConditions env s = case s of + C.FunconSpec (C.FRules nm sig mcs rs ss) + -> C.FunconSpec (C.FRules nm sig mcs rs' ss')+ where rs' = map mvarRs rs+ ss' = map mvarSs ss+ _ -> s+ where mvarRs r@(C.FRewriteRule p f ss) = + -- added last to ensure bindings+ C.FRewriteRule p f (ss ++ M.foldrWithKey op [] env)+ where op x (C.ElemOf ty) acc = case x `S.member` patvars of+ True -> C.SCIsInSort (C.TVar x) ty : acc+ False -> acc+ op x (C.SubTyOf _) acc = acc+ patvars = pvars r+ mvarSs r@(C.FStepRule f scs) = C.FStepRule f (scs ++ M.foldrWithKey op [] env)+ where patvars = pvars r+ op x (C.ElemOf ty) acc = case x `S.member` patvars of+ True -> Right (C.SCIsInSort (C.TVar x) ty) : acc+ False -> acc+ op x (C.SubTyOf _) acc = acc++-- add side-conditions to rules based on the declarations of meta-variables++simplifyTypeEnv :: MonadError String m => TypeEnv -> m C.TypeEnv+simplifyTypeEnv = mapM simplifyTyAssoc++simplifyTyAssoc :: MonadError String m => TyAssoc -> m C.TyAssoc+simplifyTyAssoc (ElemOf t) = C.ElemOf <$> simplifyFTerm t+simplifyTyAssoc (SubTyOf t) = C.SubTyOf <$> simplifyFTerm t++type KindMap = M.Map Name {- type name -} Kind+data Kind = DataType | Type deriving (Show, Enum)++simplifyCBSSpec :: MonadError String m => KindMap -> C.TypeEnv -> CBSSpec -> m [C.CBSSpec]+simplifyCBSSpec _ _ (TypeSynonymSpec spec) = return . C.FunconSpec <$> simplifyTypeSynonymSpec spec+simplifyCBSSpec km tyenv (TypeSpec spec) = simplifyCBSSpec km tyenv (DataTypeSpec spec)+simplifyCBSSpec _ tyenv (DataTypeSpec spec@(DataTypeDecl tynm typarams alts)) = do + conss <- forM alts $ \alt -> case alt of + DataTypeInclusion _ -> return mzero+ DataTypeConstructor nm sorts -> do + sorts' <- mapM simplifyFTerm sorts+ typarams' <- mapM (simplifyParamPattern tyenv) typarams+ return [genDataValCons tynm typarams' nm sorts']+ dspec <- simplifyDataTypeSpec tyenv spec+ return (C.DataTypeSpec dspec : msum conss)+simplifyCBSSpec km _ (FunconSpec spec@(FRules sig rules))+ | Just (tyname, kind) <- mNameKind -- recognised as a value-constructor+ , null rules -- and definition is missing+ = do args <- mapM sortInPattern (sigParams sig)+ typarams <- maybe (return []) (mapM toTypeParam) $ termArgs (sigSort sig)+ sig' <- mkCSig kind+ return [C.ConsSpec (C.ValCons (sigName sig) sig'+ args tyname typarams)]+ where toTypeParam t = term2tpat <$> simplifyFTerm t+ mNameKind = case sigSort sig of+ TName tnm -> fmap (tnm,) (M.lookup tnm km)+ TApp tnm _ -> fmap (tnm,) (M.lookup tnm km)+ _ -> Nothing+ where nameOf (TName nm) = nm+ nameOf (TApp nm _) = nm+ nameOf t = error ("nameOf assert1: " ++ show t)+ mkCSig kind = case kind of + DataType -> return C.DataTypeCons+ Type -> C.TypeCons <$> simplifyFSig sig+ sortInPattern (_, Nothing) = throwError ("constructor " ++ (sigName sig) ++ " without typed arguments")+ sortInPattern (_, Just sort) = simplifyFTerm sort+ +simplifyCBSSpec _ _ (FunconSpec spec) = return . C.FunconSpec <$> simplifyFunconSpec spec+simplifyCBSSpec _ _ (EntitySpec spec) = return . C.EntitySpec <$> simplifyEntitySpec spec+simplifyCBSSpec _ _ (MetaSpec spec) = return . return $ C.MetaSpec spec ++simplifyTypeSynonymSpec :: MonadError String m => TypeSynonymSpec -> m C.FunconSpec+simplifyTypeSynonymSpec (TypeSynonymDecl n ps ty) =+ simplifyFunconSpec $ + FAbbrv (FSig n ps (TName "types") Nothing) (Just ty)++genDataValCons :: Name -> [C.TPattern] -> Name -> [C.FSort] -> C.CBSSpec+genDataValCons tynm typarams nm ptypes = + C.ConsSpec (C.ValCons nm C.DataTypeCons ptypes tynm typarams)++simplifyDataTypeSpec :: MonadError String m => C.TypeEnv -> DataTypeSpec -> m C.DataTypeSpec+simplifyDataTypeSpec tyenv (DataTypeDecl nm ps alts) =+ C.DataTypeDecl nm <$> mapM (simplifyParamPattern tyenv) ps <*> simplifyDataTypeAlts alts++simplifyParamPattern :: MonadError String m => + C.TypeEnv -> FParam -> m (C.TPattern)+simplifyParamPattern tyenv (pat,_) = simplifyPat pat + where simplifyPat (PPMetaVar var) = return $ C.TPVar var + simplifyPat PPAny = return $ C.TPWildCard+ simplifyPat (PPSeqMetaVar var op) = return $ C.TPSeqVar var op++simplifyDataTypeAlts :: MonadError String m => [DataTypeAlt] -> m [C.DataTypeAlt]+simplifyDataTypeAlts alts = concat <$> mapM simplifyDataTypeAlt alts+simplifyDataTypeAlt :: MonadError String m => DataTypeAlt -> m [C.DataTypeAlt]+simplifyDataTypeAlt (DataTypeInclusion term) = + return . C.DataTypeInclusion <$> simplifyFTerm term+simplifyDataTypeAlt (DataTypeConstructor nm terms) = return []++simplifyEntitySpec :: MonadError String m => EntitySpec -> m C.EntitySpec+simplifyEntitySpec (InheritedSpec (name,term,_))+ = C.InheritedSpec name <$> simplifyFTerm term+simplifyEntitySpec (MutableSpec (name1,term,ty1) (name2,_,ty2))+ = do guardM (name1 == name2) "mutable entity name mismatch"+ guardM (ty1 == ty2) "mutable entity type mismatch"+ C.MutableSpec name1 <$> simplifyFTerm term++simplifyEntitySpec (InputSpec (name,_,ty)) =+ return (C.InputSpec name)++simplifyEntitySpec (OutputSpec (name,_,ty)) =+ do guardM (isAppOf "lists" ty) "output entities must be declared to contain lists"+ return (C.OutputSpec name)++simplifyEntitySpec (ControlSpec (name,ty)) =+ do guardM (isSortSeq QuestionMarkOp ty) "control entities must be declared to contain option types `(T)?`"+ return (C.ControlSpec name)+++simplifyFunconSpec :: MonadError String m => FunconSpec -> m C.FunconSpec++simplifyFunconSpec (FAbbrv sig mterm)+ = do term' <- maybe (return Nothing) ((Just <$>) . simplifyFTerm) mterm+ mdoc <- sMDoc (sigDoc sig)+ params <- mapM abbrvParamPatt (sigParams sig)+ sig' <- simplifyFSig sig+ return $ C.FRules (sigName sig) sig' mdoc + [ C.FRewriteRule params term' [] ] []+simplifyFunconSpec (FRules sig rules) = do+ mdoc <- sMDoc (sigDoc sig)+ sig' <- simplifyFSig sig+ uncurry (C.FRules n sig' mdoc) <$> simplifyFRules n rules+ where+ n = sigName sig+++sMDoc :: MonadError String m => Maybe [CommentPart] -> m (Maybe [C.CommentPart])+sMDoc Nothing = return Nothing+sMDoc (Just cs) = Just <$> mapM sCommentPart cs++sCommentPart :: MonadError String m => CommentPart -> m C.CommentPart+sCommentPart (Ordinary o) = return $ C.Ordinary o+sCommentPart (Asterisk) = return $ C.Asterisk+sCommentPart (At s) = return $ C.At s+sCommentPart (SpecInComment spec) = do+ specs <- simplifyCBSSpec M.empty M.empty spec+ case specs of + [cspec] -> return (C.SpecInComment cspec)+ _ -> throwError "multi-spec in comment"+sCommentPart (CommentTerm t) = return $ C.CommentTerm t+sCommentPart (CommentPremise f) = return $ C.CommentPremise f+ +simplifyFSig :: MonadError String m => FSig -> m C.FSig+simplifyFSig (FSig nm ps sort mcs) + | null ps = return C.FNullary+ | and strictArgs = return C.FStrict+ | not (or strictArgs) = return C.FLazy + -- checks requirement that only last parameter is variadic, if any+ | any isVariadic (init ps) = + throwError (nm ++ " not a valid variadic funcon")+ | or strictArgs+ , not variadic = return $ + C.FPartiallyLazy (map toStrict strictArgs) Nothing + | otherwise {-or strictArgs+ , variadic-} = return $ + C.FPartiallyLazy (map toStrict (init strictArgs)) + (Just $ toStrict (last strictArgs))+ where strictArgs = map isStrictParam ps+ variadic = isVariadic (last ps)+ toStrict strict = if strict then C.Strict else C.Lazy+++simplifyFRules :: MonadError String m => Name -> [FRule] -> m ([C.FRewriteRule],[C.FStepRule])+simplifyFRules n rs = partitionEithers <$> mapM (simplifyFRule n) rs+++simplifyFRule :: MonadError String m => Name -> FRule -> m (Either C.FRewriteRule C.FStepRule)+simplifyFRule n (FRuleRewrite name mpats rhs conds)+ = do guardM (n == name) ("rule name '" <> name <> "' does not match signature '" <> n <> "'")+ pats <- topLevelFPatterns (maybePattsToPatts mpats)+ rhs' <- case rhs of Nothing -> return Nothing+ Just t -> Just <$> simplifyFTerm t+ Left <$> C.FRewriteRule pats rhs' <$> mapM simplifyFSideCondition conds++simplifyFRule n (FRuleStep name st ps_cs)+ = do guardM (n == name) ("rule name '" <> name <> "' does not match signature '" <> n <> "'")+ st' <- simplifyFStep st+ ps_cs' <- mapM (traverseEither simplifyFPremiseStep simplifyFSideCondition) ps_cs+ guardM (all (== entitiesOfStep st') (map entitiesOfPremiseStep $ lefts ps_cs')) "the entities in a premise must match the entites used in the conclusion"+ return $ Right $ C.FStepRule st' ps_cs'++simplifyFSideCondition :: MonadError String m => FSideCondition -> m C.FSideCondition+simplifyFSideCondition (SCEquality e1 e2) =+ C.SCEquality <$> simplifyFTerm e1 <*> simplifyFTerm e2+simplifyFSideCondition (SCInequality e1 e2) =+ C.SCInequality <$> simplifyFTerm e1 <*> simplifyFTerm e2+simplifyFSideCondition (SCPatternMatch e p) =+ C.SCPatternMatch <$> simplifyFTerm e <*> topLevelFPatterns p+simplifyFSideCondition (SCIsInSort e ty) =+ C.SCIsInSort <$> simplifyFTerm e <*> simplifyFTerm ty++simplifyFStep :: MonadError String m => FStep -> m C.FStep+simplifyFStep st+ = do mut <- uncurry (mergeAssocListsM "mismatched mutable entities in conclusion") (stepMutableEntities st)+ mut' <- mapM simplifyMutableEntity mut+ inp <- mapM (uncurry simplifyInputEntity) (stepInputEntities st)+ ctrl <- mapM (uncurry simplifyControlEntity) (stepControlEntities st)+ outs <- mapM (uncurry simplifyNameTermPair) (stepOutputEntities st)+ inhs <- mapM (uncurry simplifyNamePatternsPair) (stepInheritedEntities st)+ source <- topLevelFPatterns (maybePattsToPatts (stepSource st))+ target <- simplifyFTerm (stepTarget st)+ return $ C.FStep+ { C.stepSource = source+ , C.stepTarget = target+ , C.stepInheritedEntities = inhs+ , C.stepMutableEntities = mut'+ , C.stepInputEntities = inp+ , C.stepOutputEntities = outs+ , C.stepControlEntities = ctrl+ }++simplifyFPremiseStep :: MonadError String m => FPremiseStep -> m C.FPremiseStep+simplifyFPremiseStep pst+ = do mut <- uncurry (mergeAssocListsM "mismatched mutable entities in premise")+ (premiseMutableEntities pst)+ mut' <- mapM simplifyMutableEntityPremise mut+ ctrl <- mapM (uncurry simplifyControlEntityPremise) (premiseControlEntities pst)+ outs <- mapM (uncurry simplifyNamePatternPair) (premiseOutputEntities pst)+ ins <- mapM (uncurry simplifyInputEntityPremise) (premiseInputEntities pst)+ inhs <- mapM (uncurry simplifyNameTermPair) (premiseInheritedEntities pst)+ source <- simplifyFTerm (premiseSource pst)+ target <- topLevelFPatterns (premiseTarget pst)+ return $ C.FPremiseStep+ { C.premiseSource = source+ , C.premiseTarget = target+ , C.premiseInheritedEntities = inhs+ , C.premiseMutableEntities = mut'+ , C.premiseInputEntities = ins+ , C.premiseOutputEntities = outs+ , C.premiseControlEntities = ctrl+ }++simplifyMutableEntity :: MonadError String m => (Name, FPattern, FTerm) -> m (Name, C.FPattern, C.FTerm)+simplifyMutableEntity (n,p,t) = (n,,) <$> simplifyFPattern p <*> simplifyFTerm t++simplifyInputEntity :: MonadError String m => Name -> FPattern -> m (Name,[C.FPattern],[MetaVar])+simplifyInputEntity n p = case p of+ PSeq ps -> splitInputPattern ps+ PList ps -> splitInputPattern ps+ _ -> splitInputPattern [p]+ where + takeStarMetaVars :: ([FPattern],[MetaVar]) -> ([FPattern],[MetaVar])+ takeStarMetaVars (PSeqMetaVar mv StarOp : ps', mvs) = + takeStarMetaVars (ps',mv:mvs)+ takeStarMetaVars pmvs = pmvs+ splitInputPattern ps = + (n,,reverse rmvs) <$> topLevelFPatterns (reverse rps)+ where (rps,rmvs) = takeStarMetaVars (reverse ps,[])++-- special meaning of tuple notation for control entities+simplifyControlEntity :: MonadError String m => Name -> FPattern -> m (Name,Maybe C.FPattern)+simplifyControlEntity n (PSeq []) = return (n,Nothing)+simplifyControlEntity n t = (n,) . Just <$> simplifyFPattern t++simplifyMutableEntityPremise :: MonadError String m => (Name, FTerm, FPattern) -> m (Name, C.FTerm, C.FPattern)+simplifyMutableEntityPremise (n,t,p) = (n,,) <$> simplifyFTerm t <*> simplifyFPattern p++-- special meaning of tuple notation for control entities+simplifyControlEntityPremise :: MonadError String m => Name -> FPattern -> m (Name,Maybe C.FPattern)+simplifyControlEntityPremise n (PSeq []) = return (n,Nothing)+simplifyControlEntityPremise n p = (n,) . Just <$> simplifyFPattern p++simplifyNamePatternPair :: MonadError String m => Name -> FPattern -> m (Name,C.FPattern)+simplifyNamePatternPair n p = (n,) <$> simplifyFPattern p++simplifyNamePatternsPair :: MonadError String m => Name -> [FPattern] -> m (Name,[C.FPattern])+simplifyNamePatternsPair n p = (n,) <$> topLevelFPatterns p+++simplifyInputEntityPremise :: MonadError String m => Name -> FTerm -> m (Name,[C.FTerm],Maybe MetaVar)+simplifyInputEntityPremise n t = case t of+ TList [] -> return (n,[],Nothing)+ TList ts -> splitInputTerms ts+ TTuple [] -> return (n,[],Nothing)+ TTuple ts -> splitInputTerms ts+ _ -> throwError $ "premise input entity " ++ n ++ " not a list or sequence of terms: " ++ show t+ where splitInputTerms ts = do + ts' <- mapM simplifyFTerm ts+ case last ts' of+ C.TVar mv | last mv == '*' -> return (n,init ts',Just mv)+ _ -> return (n,ts',Nothing)++simplifyNameTermPair :: MonadError String m => Name -> FTerm -> m (Name,C.FTerm)+simplifyNameTermPair n t = (n,) <$> simplifyFTerm t++topLevelFPatterns :: MonadError String m => [FPattern] -> m [C.FPattern]+topLevelFPatterns xs = concat <$> mapM simplifyFPatterns xs++simplifyFPatterns :: MonadError String m => FPattern -> m [C.FPattern]+simplifyFPatterns (PSeq pats) = concat <$> + mapM (\x -> map C.PValue <$> simplify2VPatterns x) pats+simplifyFPatterns p = (:[]) <$> simplifyFPattern p++simplifyFPattern :: MonadError String m => FPattern -> m C.FPattern+simplifyFPattern (PAnnotated pat sort) = C.PAnnotated <$> simplifyFPattern pat+ <*> simplifyFTerm sort+simplifyFPattern PAny = return C.PWildCard+simplifyFPattern (PMetaVar var) = return (C.PMetaVar var)+simplifyFPattern (PSeqMetaVar var op) = return (C.PSeqVar var op)+simplifyFPattern vpat = C.PValue <$> simplify2VPattern vpat++simplify2VPatterns :: MonadError String m => FPattern -> m [C.VPattern]+simplify2VPatterns (PSeq pats) = concat <$> mapM simplify2VPatterns pats+simplify2VPatterns p = (:[]) <$> simplify2VPattern p++simplify2VPattern :: MonadError String m => FPattern -> m C.VPattern+simplify2VPattern (PSeq pats) = error "sequence in simple pattern" +simplify2VPattern (PList pats) = C.PADT "datatype-value" <$> + (((C.VPLit (string__ "list")):) . concat <$> mapM simplify2VPatterns pats)+simplify2VPattern (PADT cons pats) = C.PADT (pack cons) <$> + (concat <$> mapM simplify2VPatterns pats)+simplify2VPattern (PLit lit) = return (C.VPLit (simplifyLiteral lit))+simplify2VPattern (PAnnotated pat sort) = C.VPAnnotated <$> simplify2VPattern pat+ <*> simplifyFTerm sort+simplify2VPattern PAny = return C.VPWildCard+simplify2VPattern (PMetaVar var) = return (C.VPMetaVar var)+simplify2VPattern (PSeqMetaVar var op) = return (C.VPSeqVar var op)+++simplifyFTerm :: MonadError String m => FTerm -> m C.FTerm+simplifyFTerm (TMetaVar var) = return $ C.TVar var+simplifyFTerm (TLiteral lit) = return $ C.TFuncon $ FValue $ simplifyLiteral lit+simplifyFTerm (TName nm) = return $ C.TName (pack nm)+simplifyFTerm (TApp nm term) = C.TApp (pack nm) <$> mapM simplifyFTerm term+simplifyFTerm (TTuple terms) = C.TSeq <$> mapM simplifyFTerm terms+simplifyFTerm (TList terms) = C.TApp "list" <$> mapM simplifyFTerm terms+simplifyFTerm (TSet terms) = C.TSet <$> mapM simplifyFTerm terms+simplifyFTerm (TMap terms) = C.TMap <$> mapM simplifyFTerm terms+simplifyFTerm (TBinding t1 t2) = C.TBinding <$> simplifyFTerm t1 <*> simplifyFTerm t2+simplifyFTerm (TSortUnion t1 t2) = C.TSortUnion <$> simplifyFTerm t1 <*>+ simplifyFTerm t2+simplifyFTerm (TSortInter t1 t2) = C.TSortInter <$> simplifyFTerm t1 <*>+ simplifyFTerm t2+simplifyFTerm (TSortComplement t1) = C.TSortComplement <$> simplifyFTerm t1+simplifyFTerm (TSortSeq t1 op) = C.TSortSeq <$> simplifyFTerm t1 <*> pure op+simplifyFTerm (TSortComputes term) = C.TSortComputes <$> simplifyFTerm term+simplifyFTerm (TSortComputesFrom t1 t2) = C.TSortComputesFrom <$> simplifyFTerm t1+ <*> simplifyFTerm t2+simplifyFTerm (TSortPower t1 t2) = C.TSortPower <$> simplifyFTerm t1 <*> simplifyFTerm t2+simplifyFTerm TAny = return C.TAny++--------------------------------------------------------------------++isAppOf :: String -> FTerm -> Bool+isAppOf n (TApp f _) = f == n+isAppOf _ _ = False++isSortSeq :: SeqSortOp -> FTerm -> Bool+isSortSeq op1 (TSortSeq _ op2) = op1 == op2+isSortSeq _ _ = False++abbrvParamPatt :: MonadError String m => FParam -> m C.FPattern+abbrvParamPatt (pp, sorts) = case sorts of+ Just sort | isStrictSort sort -> do + sort' <- simplifyFTerm sort+ return $ C.PAnnotated p sort'+ _ -> return p+ where+ p = case pp of+ PPAny -> C.PWildCard+ PPMetaVar mvar -> C.PMetaVar mvar+ PPSeqMetaVar mvar op -> C.PSeqVar mvar op++-- Interpret "f()" as a pattern matching an empty tuple argument+maybePattsToPatts :: Maybe [FPattern] -> [FPattern]+maybePattsToPatts Nothing = []+maybePattsToPatts (Just []) = [ PSeq [] ]+maybePattsToPatts (Just ps) = ps++entitiesOfStep :: C.FStep -> ([Name],[Name],[Name],[Name],[Name])+entitiesOfStep st = ( map fst (C.stepInheritedEntities st)+ , map (\(n,_,_) -> n) (C.stepMutableEntities st)+ , map (\(n,_,_) -> n) (C.stepInputEntities st)+ , map fst (C.stepOutputEntities st)+ , map fst (C.stepControlEntities st)+ )++entitiesOfPremiseStep :: C.FPremiseStep -> ([Name],[Name],[Name],[Name],[Name])+entitiesOfPremiseStep st =+ ( map fst (C.premiseInheritedEntities st)+ , map (\(n,_,_) -> n) (C.premiseMutableEntities st)+ , map (\(n,_,_) -> n) (C.premiseInputEntities st)+ , map fst (C.premiseOutputEntities st)+ , map fst (C.premiseControlEntities st)+ )++--------------------------------------------------------------------++term2tpat :: C.FTerm -> C.TPattern+term2tpat t = case t of + C.TSortComputes f -> C.TPComputes (term2tpat f) + C.TSortComputesFrom f t -> C.TPComputesFrom (term2tpat f) (term2tpat t)+ C.TSortSeq (C.TVar x) op -> C.TPSeqVar x op+ C.TVar x -> C.TPVar x+ C.TAny -> C.TPWildCard+ C.TName nm -> C.TPADT nm []+ C.TApp nm ts -> C.TPADT nm (map term2tpat ts)+ _ -> C.TPLit t
+ src/Simplify/TargetToFunconModules.hs view
@@ -0,0 +1,124 @@+{-# Language FlexibleContexts, ScopedTypeVariables, LambdaCase+ , MultiParamTypeClasses, TupleSections, FlexibleInstances #-}++module Simplify.TargetToFunconModules where++import Control.Arrow ((***))+import CCO.Component (Component, component)+import Data.Text (pack)++--------------------------------------------------------------------+import Funcons.EDSL (type_, Funcons(FValue), Values(..), FTerm(..), string__, DataTypeMembers(..), DataTypeAltt(..), pat2term)+import Types.SourceAbstractSyntax (Name, FLiteral(..))+import Types.CoreAbstractSyntax (FSig(..), FTerm(TSeq), funconIsNullary, ConsSpec(..), DataTypeSpec(..), DataTypeAlt(..))+import Types.TargetAbstractSyntax+import qualified Types.FunconModule as F+import Simplify.Utils+--------------------------------------------------------------------++-- require for forming a pipeline with uu-cco library+target2fmodule :: Bool -> Component CBSFile F.FunconModule+target2fmodule gen_ph = component (return . simplifyCBSFile gen_ph)++simplifyCBSFile :: Bool -> CBSFile -> F.FunconModule+simplifyCBSFile gen_ph cbsfile = + let fspecs = concatMap (simplifyFunconSpec gen_ph) (funcons cbsfile)+ in F.FunconModule fspecs+ (entities cbsfile) + (map (gTypeMember (constructors cbsfile)) (datatypes cbsfile))+ (env cbsfile)+ (aliases cbsfile)++gTypeMember :: [ConsSpec] -> DataTypeSpec -> DataTypeMembers+gTypeMember css (DataTypeDecl nm typarams alts) = + DataTypeMemberss (pack nm) typarams (concatMap gAlts alts ++ gCons)+ where gAlts (Types.CoreAbstractSyntax.DataTypeInclusion term) = + [Funcons.EDSL.DataTypeInclusionn term]+ gCons = foldr op [] css+ where op (ValCons cons _ args nm' tparams) acc+ | nm == nm' = Funcons.EDSL.DataTypeMemberConstructor (pack cons) args (Just tparams):acc+ | otherwise = acc++simplifyFunconSpec :: Bool -> FunconSpec -> [F.FunconSpec]+simplifyFunconSpec gen_ph (FRules _ _ _ [] [])+ | not gen_ph = [] -- remove funcons without rules+simplifyFunconSpec _ (FRules nm sig mdoc rewrites steps) = + let rewrites' = map (simplifyRewriteRule sig) rewrites+ steps' = map (simplifyStepRule sig) steps+ in [F.FunconSpec nm sig mdoc rewrites' steps']++simplifyRewriteRule :: FSig -> FRewriteRule -> [F.FRewriteStmt]+simplifyRewriteRule sig (FRewriteRule pats mterm sides) = + source ++ sideconditions ++ [target]+ where source | funconIsNullary sig = []+ | otherwise = [F.ArgsPattern F.fargs_var pats]+ sideconditions = map F.CheckSideCondition sides+ target = F.RewriteTarget (maybe (TSeq []) id mterm)++simplifyStepRule :: FSig -> FStepRule -> [F.FStepStmt]+simplifyStepRule sig (FStepRule fstep e_prem_sides) = + source_pat +++ source_mut_ps +++ source_inhs ++ + source_inps ++ + source_dsigs +++ bar +++ target_ctrls +++ target_outs +++ source_mut_ts +++ [target]+ where source_pat + | funconIsNullary sig = [] + | otherwise = [F.FRewriteStmt(F.ArgsPattern F.fargs_var pats)]+ where pats = stepSource fstep+ target = F.StepTarget (stepTarget fstep)+ source_inhs = map (uncurry F.ReadInherited)+ (stepInheritedEntities fstep)+ (source_mut_ps,source_mut_ts) = + foldr op ([],[]) (stepMutableEntities fstep)+ where op (nm,p,t) (ps,ts) = (F.ReadMutable nm p:ps+ ,F.WriteMutable nm t:ts)+ source_inps = map (uncurry F.ReadInput) (stepInputEntities fstep) + source_dsigs = map (uncurry F.ReadDownControl) (stepControlEntities fstep)+ target_outs = map (uncurry F.WriteOutput) (stepOutputEntities fstep)+ target_ctrls = map (uncurry F.WriteControl) + (map (id *** fmap pat2term) $ stepControlEntities fstep)+ bar = concatMap sel e_prem_sides+ where sel (Right side) = [F.FRewriteStmt + (F.CheckSideCondition side)]+ sel (Left prem) = premToStmts prem++ premToStmts prem = muts_ts ++ [premise] ++ sigReads ++ muts_ps+ where (muts_ts,muts_ps) = foldr op ([],[]) (premiseMutableEntities prem)+ where op (nm,t,p) (ts,ps) = (F.WriteMutable nm t:ts+ ,F.ReadMutable nm p:ps)+ sigReads = map op (premiseControlEntities prem)+ where op (nm,mpat) = F.ReadControl nm mpat+ premise = + -- receive+ flip (foldr out_op) (premiseOutputEntities prem) $+ receiveControl (premiseControlEntities prem) $+ -- scope+ flip (foldr dsigs_op) (premiseControlEntities prem) $+ flip (foldr inhs_op) (premiseInheritedEntities prem) $+ flip (foldr inps_op) (premiseInputEntities prem) $+ (F.Premise (premiseSource prem) + (premiseTarget prem))+ where + out_op :: (Name,FPattern) -> F.FStepStmt -> F.FStepStmt+ out_op (nm,pat) = F.ReceiveOutput nm pat++ inps_op :: (Name, [FTerm], InputAccess) -> F.FStepStmt + -> F.FStepStmt+ inps_op (nm, fcts, acc) = F.ScopeInput nm fcts acc+ + inhs_op :: (Name, FTerm) -> F.FStepStmt -> F.FStepStmt+ inhs_op (nm, fct) = F.ScopeInherited nm fct + + dsigs_op :: (Name, Maybe FPattern) -> F.FStepStmt -> F.FStepStmt+ dsigs_op (nm, fct) = F.ScopeDownControl nm (fmap pat2term fct)++ receiveControl ents + | null ents = id+ | otherwise = F.ReceiveControl (map fst $ ents)+
+ src/Simplify/TargetToIML.hs view
@@ -0,0 +1,737 @@+{-# Language FlexibleContexts, ScopedTypeVariables, FlexibleInstances, + TupleSections, OverloadedStrings #-}++module Simplify.TargetToIML where++--------------------------------------------------------------------+import Funcons.EDSL (Values(..), Funcons(FValue), isString_, unString, pat2term, typat2term)+import Types.SourceAbstractSyntax (Name, FLiteral(..), SeqSortOp(..),MetaVar, AliasMap, my_aliases)+import Types.CoreAbstractSyntax (FPattern(..), FTerm(..), isSeqVarSort,+ FSideCondition(..), DataTypeSpec(..),DataTypeAlt(..), + EntitySpec(..), ConsSpec(..), FSig(..), Strictness(..))+import Types.TargetAbstractSyntax+import Simplify.Utils+import qualified IML.Grammar as RF+import qualified IML.Grammar.Specs as IS+import qualified IML.Trans.ProMan as IML+import IML.Trans.FromFuncons (translate, remVarOp, translate_term)+import qualified Funcons.Operations as VAL+import IML.EDSL+-------------------------------------------------------------------++import Control.Arrow ((***))+import Control.Monad.Trans+import Control.Monad.Writer+import Control.Monad.State+import Data.Text (unpack,pack)+import Data.Map (assocs)+import Data.String (fromString)++import System.IO.Unsafe+trace a b = unsafePerformIO (putStrLn a >> return b)++-- | Type representing value constructors+type VCons = Name+type Cons = Name++-- | The constructor used for the type-membership predicate+stepR, tyR :: RF.RSymb+stepR = "->"+rewVR = "~>"+tyR = "=ty=>"++rewrite,step :: IsExprs exprs => exprs -> RuleBuilder ()+step = commit stepR+rewrite = commit rewVR+type_member = commit tyR (RF.TVal (VAL.tobool True))++target2iml :: IML.Component CBSFile IS.HighSpec+target2iml = IML.component (\file -> return (execRuleBuilder (gCBSFile file)))++lFSpec :: FunconSpec -> FunconSpec+lFSpec spec@(FRules nm sig mcs rs ss) = case sig of + FLazy -> spec+ FNullary -> spec+ FStrict -> FRules nm sig mcs rs' ss'+ where FRules _ _ _ rs' ss' = lFSpec + (FRules nm (FPartiallyLazy [] (Just Strict)) mcs rs ss)+ FPartiallyLazy ann mseqvar -> FRules nm sig mcs rs ss'+ where ss' = map mkRule ruleKeys ++ seqvarRule ++ ss+ ruleKeys = map fst $ filter ((Strict ==) . snd) keys+ keys = zip [1..] ann+ seqvarRule = case mseqvar of + Nothing -> []+ Just Lazy -> []+ Just Strict -> [rule] + where rule = FStepRule step (map Right scs ++ [Left premise])+ step = FStep (map mkPat (take (length ann) [1..]) ++ [PSeqVar "X*" StarOp])+ (TApp (pack nm) (map mkTerm (take (length ann) [1..]) ++ [TVar "Y*"]))+ [] [] [] [] []+ where mkPat i = PMetaVar (mkVar i)+ mkTerm i = TVar (mkVar i)+ premise = FPremiseStep (TVar "X*") [PSeqVar "Y*" StarOp] [] [] [] [] []+ mkVar i = "X" ++ show i+ scs = map mkSC ruleKeys+ where mkSC i = SCIsInSort (TVar (mkVar i)) (TSortSeq (TName "values") QuestionMarkOp)++ mkRule k = FStepRule step [Left premise] + where step = FStep pats (TApp (pack nm) terms) [] [] [] [] [] + (pats,terms) = foldr op base keys+ where base = case mseqvar of + Just _ -> ([PSeqVar "X*" StarOp]+ ,[TVar "X*"]) + _ -> ([], [])+ op (k',sness) (pats, terms) + | k' == k = (PMetaVar var:pats+ ,TVar (var ++ "'") : terms) + | k' < k, Strict <- sness = + (PAnnotated (PMetaVar var) + (TName "values"):pats+ ,TVar var : terms)+ | True = (PMetaVar var : pats, TVar var : terms)+ where var = "X" ++ show k'+ premise = FPremiseStep (TVar var) [PMetaVar (var ++ "'")] + [] [] [] [] []+ where var = "X" ++ show k +++gCBSFile :: CBSFile -> RuleBuilder () +gCBSFile cbsfile = do+ {- THESE RELATIONS ARE NOW DECLARED IN main.iml+ rel_decl stepR [{-IS.Repeatable-}]+ rel_decl rewR [{-IS.Repeatable-}]+ rel_decl tyR [] -- type-member relation+ -}+ mapM_ (gCBSSpec (aliases cbsfile)) (cbs cbsfile)++ {- THESE RULES ARE NOW SPECIFIED IN main.iml FILE + -- fall back rule for type-membership+ -- that checks whether first argument is a value+ [v1,v2,v3] <- mapM (const fresh_var) [1..3]+ lhs (RF.PCons ty_cons [RF.PVar v1, RF.PVar v2])+ gRewrite (RF.TVar v1) (RF.PVar v3)+ gRewrite (RF.TVar v2) (RF.PCons "values" [])+ is_terminating stepR (RF.TVar v3)+ commit tyR (RF.TVal (VAL.tobool True))+ -- fall back rule that determines non-membership+ [v1,v2,v3,v4,v5] <- mapM (const fresh_var) [1..5]+ lhs (RF.PCons ty_cons [RF.PVar v1, RF.PVar v2])+ gRewrite (RF.TVar v1) (RF.PVar v3)+ gRewrite (RF.TVar v2) (RF.PVar v4)+ pm (vop "type-member" [RF.TVar v3, RF.TVar v4]) (RF.PVar v5)+ commit_prio 0 tyR (RF.TVar v5)+ -}++gCBSSpec :: AliasMap -> CBSSpec -> RuleBuilder ()+gCBSSpec am (FunconSpec spec) = gFSpecWithMP_Aliases am (lFSpec spec)+gCBSSpec am (DataTypeSpec spec) = gData_Aliases am spec+gCBSSpec am (MetaSpec _) = return ()+gCBSSpec am (EntitySpec spec) = gEntitySpec spec+gCBSSpec am (ConsSpec spec) = gCons_Aliases am spec++gEntitySpec :: EntitySpec -> RuleBuilder ()+gEntitySpec spec = case spec of + InheritedSpec n t -> ent_decl n [tTermAsExpr t]+ MutableSpec n t -> ent_decl n [tTermAsExpr t]+ OutputSpec n -> ent_decl n ([] :: [RF.Expr])+ InputSpec n -> ent_decl n ([] :: [RF.Expr])+ ControlSpec n -> ent_decl n ([] :: [RF.Expr]) ++gFSpecWithMP_Aliases :: AliasMap -> FunconSpec -> RuleBuilder()+gFSpecWithMP_Aliases am (FRules nm a b c d) = + forM_ (my_aliases nm am) (\nm' -> gFSpecWithMP (FRules nm' a b c d)) + +gFSpecWithMP :: FunconSpec -> RuleBuilder () +gFSpecWithMP spec@(FRules nm sig _ _ _) = gFSpec spec >> + astFuncons nm (Just 2)-- rules for meta-programming+ where + gFSpec (FRules nm sig _ rs ss) = do + mapM_ (gRewriteRule sig nm) rs+ mapM_ (gStepRule sig nm) ss++mk_strict_lhs :: Name -> [RF.Pattern] -> RuleBuilder ()+mk_strict_lhs nm pats = do + args_var <- fresh_var+ add_var_decl_ (gVarDecl args_var (Just StarOp))+ lhs (RF.PCons nm [RF.PVar args_var])+ premise [RF.TVar args_var] (mRel rewVR) pats++mk_partial_lhs :: Name -> [RF.Pattern] -> [RF.Pattern] -> RuleBuilder ()+mk_partial_lhs nm init_pats rest_pats = do+ arg_var <- fresh_var + add_var_decl_ (gVarDecl arg_var (Just StarOp)) + lhs (RF.PCons nm (init_pats ++ [RF.PVar arg_var]))+ premise [RF.TVar arg_var] (mRel rewVR) rest_pats ++gRewriteRule :: FSig -> Name -> FRewriteRule -> RuleBuilder () +gRewriteRule sig nm (FRewriteRule source target bar) = do+ pats <- mapM tFPattern source+ case sig of FStrict -> mk_strict_lhs nm pats+ FPartiallyLazy ann (Just Strict) -> mk_partial_lhs nm init_pats rest_pats+ where (init_pats,rest_pats) = splitAt (length ann) pats+ _ -> lhs (RF.PCons nm pats)+ mapM gSideCond bar+ rewrite $ case target of Nothing -> map RF.ETerm $ tTerm2Seq (TName "null")+ Just t -> map RF.ETerm $ tTerm2Seq t +gStepRule :: FSig -> Name -> FStepRule -> RuleBuilder ()+gStepRule sig nm (FStepRule fstep bar) = do+ pats <- mapM tFPattern (stepSource fstep)+ lhs (RF.PCons nm pats)+ -- contextual/ inherited entities+ ros <- mapM gRO (stepInheritedEntities fstep)+ mapM_ (\(n, p, t) -> acc n p >> up n t) ros+ -- mutable entities (IN)+ forM (stepMutableEntities fstep) $ \(n,p,t) -> do+ tFPattern p >>= acc n+ -- TODO: input entities+ -- * The "rest" of the input must be bound by a meta-var so that+ -- the first premise can provide this as additional input+-- forM (stepInputEntities fstep) $ \(n, vars) -> +-- acc n =<< tSeqPattern (map PMetaVar vars)++ gConditions bar+ -- control entities+ forM (stepControlEntities fstep) $ \(n, mt) -> + acc n ([] :: [RF.Pattern]) >> + case mt of + Nothing -> up n ([] :: [RF.Term])+ Just t -> rewAndPut n (pat2term t)+ -- mutable entities (OUT)+ forM (stepMutableEntities fstep) $ \(n,p,t) -> do+ rewAndPut n t + -- output entities+ forM (stepOutputEntities fstep) $ \(n, t) -> do+ var1 <- fresh_var+ var2 <- fresh_var+ add_var_decl_ (gVarDecl var1 (Just StarOp))+ add_var_decl_ (gVarDecl var2 (Just StarOp))+ acc n (RF.PVar var1)+ gOptRewrite (tTerm2Seq t) [RF.PVar var2]+ up n [RF.TVar var1, RF.TVar var2]+ step (tTerm2Seq (stepTarget fstep))+-- ros <- let op (n,p) = (n,) <$> tPattern p+-- in mapM op (stepInheritedEntities fstep) --acc +-- rws <- mapM rewriteMutVal (stepMutableEntities fstep)+-- wos1 <- mapM (uncurry rewriteOutVal) (stepOutputEntities fstep)+-- wos2 <- mapM (uncurry rewriteConVal) (stepControlEntities fstep)+-- let conditions = --concatMap (map Left . fst) wos1 +++ --concatMap (map Left . fst) rws +++ --concatMap (map Left . fst) wos2 ++ + where gRO (n,ps) = case ps of+ [] -> return (n, [], []) + [PMetaVar var]-> return (n, [RF.PVar var], [RF.TVar var])+ [PWildCard] -> do var <- fresh_var+ return (n, [RF.PVar var],[RF.TVar var])+ _ -> do var <- fresh_var+ add_var_decl_ (gVarDecl var (Just StarOp))+ gSideCond (SCPatternMatch (TVar var) ps)+ return (n, [RF.PVar var], [RF.TVar var])+ rewAndPut n t = do var <- fresh_var + gOptRewrite (tTerm2Seq t) [RF.PVar var]+ up n (RF.TVar var)++gConditions :: [Either FPremiseStep FSideCondition] -> RuleBuilder () +gConditions cs = mapM_ (mapeither gPremise gSideCond) cs+ where mapeither f _ (Left e) = f e+ mapeither _ f (Right e) = f e++gPremise :: FPremiseStep -> RuleBuilder ()+gPremise pstep = do + target' <- mapM tFPattern (premiseTarget pstep)+ let source' = tTerm2Seq (premiseSource pstep)+ var <- fresh_var+ add_var_decl_ (gVarDecl var (Just StarOp)) + gOptRewrite source' [RF.PVar var]+ -- contextual/inherited entities + inhI <- forM (premiseInheritedEntities pstep) $ \(n,t) -> do+ var <- fresh_var + gOptRewrite (tTerm2Seq t) [RF.PVar var]+ add_var_decl_ (gVarDecl var (Just StarOp))+ return (n, [RF.ETerm $ RF.TVar var])+ + -- mutable entities+ mutI <- forM (premiseMutableEntities pstep) $ \(n,t,p) -> do+ var <- fresh_var + gOptRewrite (tTerm2Seq t) [RF.PVar var]+ return (n, [RF.ETerm (RF.TVar var)])+ mutO <- mapM (\(n,t,p) -> (n,) . (:[]) <$> tFPattern p)+ (premiseMutableEntities pstep)+ -- output entities+ let outI = map (\(n,_) -> (n, []))+ (premiseOutputEntities pstep)+ let matchOutList n p = case p of+ (PValue (PADT "list" ps)) -> (n,) <$> tSeqPattern (map PValue ps) -- TODO pattern matching lists currently not supported, requires usage of destructors like `head` and `tail`+ _ -> error "premise output not formed by a list of patterns"+ outO <- mapM (uncurry matchOutList) (premiseOutputEntities pstep)+ -- control entities+ let ctrlI = map (\(n,_) -> (n, [])) + (premiseControlEntities pstep)+ ctrlO <- forM (premiseControlEntities pstep) $ \(n,mp) -> case mp of + Just p -> (n,) . (:[]) <$> tFPattern p+ Nothing -> return (n, [])+ -- TODO: input entities + --ExtraInput determines that there is `other` input than provided by the terms+ -- this input is the `left over' from the conclusion (or last premise?)+ {-+ inpI <- forM (premiseInputEntities pstep) $ \(n,vars,_) -> do+ var <- fresh_var+ gRewriteExpr (vop "list" (map tTerm vars)) (RF.PVar var)+ return (n, RF.TVar var)-}+ -- Check whether all provided input has been consumed.+ -- If ExtraInput than more may be consumed+ -- If ExactInput than inpO must be equal to []+ {- let inpO = map (\(n,_,access) -> -}+-- woaccs <- let op (n,p) = (n,) <$> tPattern p+-- opm (n,Nothing) = (n++"-nothing",) . RF.PVar <$> IML.fresh_var_+-- opm (n,Just p) = op (n,p) +-- in (++) <$> mapM op (premiseOutputEntities pstep)+-- <*> mapM opm (premiseControlEntities pstep)+-- inhs <- mapM (uncurry rewriteOutVal) (premiseInheritedEntities pstep)+-- muts <- mapM rewriteMutVal (premiseMutableEntities pstep)+-- let roups = map snd inhs+-- rwups = map snd muts+ let ins = inhI ++ mutI ++ outI ++ ctrlI -- ++ inpI+ outs = mutO ++ outO ++ ctrlO -- ++ inpO+ refocus_var <- fresh_var -- static refocussing 1/4+ add_var_decl_ (gVarDecl refocus_var (Just StarOp)) -- static refocussing 2/4+ premise (RF.TConf [RF.ETerm (RF.TVar var)] ins) stepR (RF.PConf [RF.PVar refocus_var] []) -- static refocussing 3/4+ premise (RF.TConf [RF.ETerm (RF.TVar refocus_var)] []) (mRel stepR) (RF.PConf target' outs) -- static refocussing 4/4+-- premise (RF.TConf [RF.ETerm (RF.TVar var)] ins) stepR (RF.PConf target' outs) -- disabling static refocussing++tSeqPattern :: [FPattern] -> RuleBuilder [RF.Pattern]+tSeqPattern ps = mapM tFPattern ps+{-foldM attach (RF.PCons nil_v []) . reverse+ where attach acc p = do pat <- tPattern p+ return (RF.PCons "cons" [pat, acc])-}++gSideCond :: FSideCondition -> RuleBuilder () +gSideCond sc = + case sc of+ SCEquality t1 t2 -> mkEquality t1 t2 truePat + SCInequality t1 t2 -> mkEquality t1 t2 falsePat+ SCIsInSort t1 sort -> case sort of + TSortComplement sort' -> mkSort t1 sort' falsePat+ _ -> mkSort t1 sort truePat+ SCNotInSort t1 sort -> mkSort t1 sort falsePat+ SCPatternMatch t ps -> do+ ps' <- mapM tFPattern ps+ gOptRewriteExpr (map RF.ETerm $ tTerm2Seq t) ps'+ where mkEquality (TSeq []) t2 _ = gSideCond (SCPatternMatch t2 [])+ mkEquality t1 (TSeq []) _ = gSideCond (SCPatternMatch t1 [])+ mkEquality (TName "true") t _ = gRewriteTo (tTerm t) truePat+ mkEquality t (TName "true") _ = gRewriteTo (tTerm t) truePat+ mkEquality (TName "false") t _= gRewriteTo (tTerm t) falsePat+ mkEquality t (TName "false") _= gRewriteTo (tTerm t) falsePat+ mkEquality t1 t2 b = do+ v1 <- fresh_var+ gRewriteToVal (tTerm2Seq t1) v1+ v2 <- fresh_var+ gRewriteToVal (tTerm2Seq t2) v2+ pm (vop "is-equal" [RF.TVar v1, RF.TVar v2]) b+{- mkSort (TVar v1) sort b + | let mop = last v1, mop == '*' || mop == '?' || mop == '+' = + let tup = TTuple [TVar v1]+ seqs = TApp "tyseq" (TTuple [sort, TFuncon (FValue (String [mop]))])+ in mkSort tup seqs b-}+ mkSort t1 sort b = + tycheck t1' sort' b --rewriting performed in rules for tychecking+ where (t1',sort') = (tTerm2Seq t1, maybeApplyTySeq sort)+ +tycheck :: [RF.Term] -> RF.Term -> RF.Pattern -> RuleBuilder ()+tycheck vals ty b = premise (ty : vals) (mRel tyR) b++tycheck_direct :: [RF.Term] -> RF.Term -> RF.Pattern -> RuleBuilder ()+tycheck_direct vals ty b = premise (ty : vals) (sRel tyR) b++maybeApplyTySeq :: FTerm -> RF.Term+maybeApplyTySeq sort + | isSeqVarSort sort = ty'+ | otherwise = case tys of [ty] -> ty+ _ -> ty'+ where tys = tTerm2Seq sort+ ty' = RF.TCons "tyseq" tys++lit2Val :: VAL.HasValues t => FLiteral -> VAL.Values t +lit2Val lit = case lit of+ FLiteralNat nat -> VAL.Nat (toInteger nat)+ FLiteralFloat f -> VAL.Float f + FLiteralString s -> fromString s+ FLiteralAtom c -> fromString c+++-- | Assuming no other patterns than the conclusions' left-hand side+-- have annotation. For other patterns it is safe to use `tPattern`+tFPattern :: FPattern -> RuleBuilder RF.Pattern+tFPattern (PValue vpat) = tVPattern vpat+tFPattern (PAnnotated PWildCard sort) = do+ v <- fresh_var+ tFPattern (PAnnotated (PMetaVar v) sort)+tFPattern (PAnnotated (PMetaVar v) sort) = do+ add_var_decl_ (gVarDecl v Nothing) + tycheck [RF.TVar v] (maybeApplyTySeq sort) truePat + return (RF.PVar v)+tFPattern (PAnnotated (PSeqVar v op) sort) + | v == "___" = fresh_var >>= \v' -> tFPattern (PAnnotated (PSeqVar v' op) sort)+ | otherwise = do+ add_var_decl_ (gVarDecl (remVarOp v) (Just op))+ tycheck [RF.TVar (remVarOp v)] (maybeApplyTySeq sort) truePat+ return (RF.PVar (remVarOp v))+tFPattern (PAnnotated p v) = error "unexpected annotation"+tFPattern (PMetaVar var) = return $ RF.PVar var+tFPattern (PSeqVar var op)+ | var == "___" = fresh_var >>= \v' -> tFPattern (PSeqVar v' op)+ | otherwise = do+ add_var_decl_ (gVarDecl (remVarOp var) (Just op))+ return $ RF.PVar (remVarOp var)+tFPattern PWildCard = RF.PVar <$> fresh_var++tVPattern :: VPattern -> RuleBuilder RF.Pattern+tVPattern (VPAnnotated VPWildCard sort) = do+ v <- fresh_var+ tVPattern (VPAnnotated (VPMetaVar v) sort)+tVPattern (VPAnnotated (VPMetaVar v) sort) = do+ add_var_decl_ (gVarDecl v Nothing)+ return (RF.PVar v)+tVPattern (VPAnnotated (VPSeqVar v op) sort) + | v == "___" = fresh_var >>= \v' -> tVPattern (VPAnnotated (VPSeqVar v' op) sort) + | otherwise = do+ add_var_decl_ (gVarDecl (remVarOp v) (Just op))+ tycheck [RF.TVar (remVarOp v)] (maybeApplyTySeq sort) truePat+ return (RF.PVar (remVarOp v))+tVPattern (VPAnnotated p v) = error "unexpected annotation"+tVPattern (PADT cons ps)+ -- TODO: generate variable with conditions that say that :+ -- a) the matched value has `adt-constructor` equal to `string__ cons`+ -- b) the matched value has `adt-fields` that match the patterns `ps`+ | cons == "datatype-value", not (null ps) = do+ p' <- tVPattern (head ps)+ ps' <- mapM tVPattern (tail ps)+ var_rewrite <- fresh_var+ var <- fresh_var+ gRewriteToVal [RF.TVar var_rewrite] var+ premise (RF.TConf [RF.VOP "adt-constructor" [RF.ETerm $ RF.TVar var]] [])+ (mRel rewVR) (RF.PConf [p'] [])+ premise (RF.TConf [RF.ETerm $ RF.TCons "list-elements" + [RF.TCons "adt-fields" [RF.TVar var]]] [])+ (mRel rewVR) (RF.PConf ps' [])+ return (RF.PVar var_rewrite) --TODO rewrite to `var` instead??+ | otherwise = do+ v <- fresh_var + pat' <- RF.PVal . VAL.ADTVal cons <$> mapM tVPattern ps+ premise (toTConf (RF.TVar v)) (mRel rewVR) (toPConf pat')+ return (RF.PVar v)+tVPattern VPWildCard = RF.PVar <$> fresh_var+tVPattern (VPMetaVar var) = return $ RF.PVar var+tVPattern (VPSeqVar var op)+ | var == "___" = fresh_var >>= \v' -> tVPattern (VPSeqVar v' op)+ | otherwise = do+ add_var_decl_ (gVarDecl (remVarOp var) (Just op))+ return $ RF.PVar (remVarOp var)+tVPattern (VPLit lit) = return $ RF.PVal (VAL.vmap (RF.term2pattern . translate) lit)+tVPattern (VPType tpat) = tTPattern tpat++tTPattern :: TPattern -> RuleBuilder RF.Pattern+tTPattern TPWildCard = RF.PVar <$> fresh_var+tTPattern (TPVar var) = return $ RF.PVar (remVarOp var)+tTPattern (TPSeqVar var op) + | var == "___" = fresh_var >>= \v' -> tTPattern (TPSeqVar v' op)+ | otherwise = do+ add_var_decl_ (gVarDecl (remVarOp var) (Just op))+ return $ RF.PVar (remVarOp var)+tTPattern (TPLit fterm) = error "missing translation for type-literals"+tTPattern (TPComputes tp) = RF.PVal . VAL.ADTVal "tycomp" . (:[]) <$> tTPattern tp +tTPattern (TPComputesFrom fp tp) = RF.PVal . VAL.ADTVal "tycomp" <$> mapM tTPattern [fp,tp]+tTPattern (TPADT cons ps) = RF.PVal . VAL.ComputationType . VAL.Type . VAL.ADT cons <$> mapM tTPattern ps ++tTerms :: [FTerm] -> [RF.Term]+tTerms = map tTerm++tTermAsExpr :: FTerm -> RF.Expr+tTermAsExpr (TName nm) = RF.VOP (unpack nm) [] +tTermAsExpr (TApp nm ts) = RF.VOP (unpack nm) (map tTermAsExpr ts)+tTermAsExpr t = RF.ETerm (tTerm t)++tTerm2Seq :: FTerm -> [RF.Term]+tTerm2Seq (TSeq ts) = concatMap tTerm2Seq ts+tTerm2Seq t = [tTerm t]++tTerm :: FTerm -> RF.Term+tTerm = translate_term++{-+tFuncons :: [Funcons] -> [RF.Term]+tFuncons = map tFuncon ++tFuncon :: Funcons -> RF.Term+tFuncon (FName nm) = RF.TCons False (unpack nm) []+tFuncon (FApp nm f) = RF.TCons False (unpack nm) $ case f of + FTuple ts -> tFuncons ts+ _ -> [tFuncon f]+tFuncon (FTuple fs) = RF.TCons False "tuple" (tFuncons fs)+tFuncon (FList fs) = RF.TCons False "list" (tFuncons fs)+tFuncon (FSet fs) = RF.TCons False "set" (tFuncons fs)+tFuncon (FMap fs) = RF.TCons False "map" (tFuncons fs)+tFuncon (FValue v) = trace "warning: missing value translations"+ $ RF.TCons True "some-value" []+tFuncon _ = error "missing Funcons translation"+-}++gVarDecl :: RF.MVar -> Maybe SeqSortOp -> RF.VarDecl+gVarDecl x mop = RF.VarDecl x lb mub RF.Longest [] + where (lb,mub) = case mop of Just StarOp -> (0, Nothing)+ Just PlusOp -> (1, Nothing)+ Just QuestionMarkOp -> (0, Just 1)+ Nothing -> (1, Just 1)++is_terminating_or_null t = tycheck [t] (RF.TCons "tystar" [RF.TCons "values" []]) truePat++gRewriteToValExpr :: [RF.Expr] -> RF.MVar -> RuleBuilder ()+gRewriteToValExpr expr var = do+ gOptRewriteExpr expr [RF.PVar var]+ is_terminating_or_null (RF.TVar var) ++gRewriteToVal :: [RF.Term] -> RF.MVar -> RuleBuilder ()+gRewriteToVal term = gRewriteToValExpr (map RF.ETerm term) ++gRewriteTo :: RF.Term -> RF.Pattern -> RuleBuilder()+gRewriteTo t p = gOptRewriteExpr [RF.ETerm t] [p] ++gOptRewriteExpr :: [RF.Expr] -> [RF.Pattern] -> RuleBuilder ()+gOptRewriteExpr expr pat = premise expr (mRel rewVR) pat++gOptRewrite :: [RF.Term] -> [RF.Pattern] -> RuleBuilder ()+gOptRewrite term = gOptRewriteExpr (map RF.ETerm term)++truePat, falsePat :: RF.Pattern+truePat = RF.PVal (VAL.tobool True)+falsePat = RF.PVal (VAL.tobool False)+ +gData_Aliases :: AliasMap -> DataTypeSpec -> RuleBuilder ()+gData_Aliases am (DataTypeDecl nm tyargs alts) = + forM_ (my_aliases nm am) (\nm' -> gData (DataTypeDecl nm' tyargs alts))+ +gData :: DataTypeSpec -> RuleBuilder ()+gData d@(DataTypeDecl nm tyargs alts) = do+ -- generate rules for inclusion constructors+ gAlts d+ --term_pc stepR (Right $ toVCons nm)+ --term_pc rewVR (Right $ toVCons nm) + -- axiom for type+ (vars,typats) <- unzip <$> mapM mkPat tyargs+ pats <- mapM tTPattern typats+ lhs (RF.PCons nm pats)+ vars' <- forM vars $ \var -> do+ var' <- fresh_var+ gRewriteToVal [RF.TVar var] var'+ return var' -- TODO share these rewrites with sidecons in bar1+ rewrite (VAL.ADT (pack nm) (map RF.TVar vars')) --rewrite+ -- congruence rules+ strictFCongs nm+ -- type alternative for type -- no longer required since ADT-builtin+ --typeMemberAltCons "types" [] nm (map snd tyargs)+ astFuncons nm (Just $ length pats) -- meta-funcons for type+ where mkPat :: TPattern -> RuleBuilder (MetaVar, TPattern)+ mkPat tpat = case tpat of+ TPVar var -> return (var, tpat)+ TPSeqVar var op -> return (remVarOp var, tpat)+ TPWildCard -> do var <- fresh_var+ return (var, TPVar var)+ _ -> error "unexpected type-parameter pattern"++gAlts :: DataTypeSpec -> RuleBuilder ()+gAlts dt@(DataTypeDecl _ _ alts) = mapM_ (gAlt dt) alts++gAlt :: DataTypeSpec -> DataTypeAlt -> RuleBuilder () +gAlt (DataTypeDecl tyname tyargs _) alt = case alt of+ DataTypeInclusion sort -> + typeMemberAltIncl tyname tyargs sort++gCons_Aliases :: AliasMap -> ConsSpec -> RuleBuilder ()+gCons_Aliases am (ValCons nm a b tynm d) = + forM_ (my_aliases nm am) (\nm' -> + forM_ (my_aliases tynm am) (\tynm' -> gCons (ValCons nm' a b tynm' d)))++gCons :: ConsSpec -> RuleBuilder()+-- SIMPLIFICATION: all constructors are strict+gCons (ValCons nm _ argstys tynm typats) = do+-- gDataTypeValue nm -- rules for the operational behaviour of cons+ typeMemberAltCons tynm typats nm argstys -- type-membership rule+ astFuncons nm (Just nr_args)+ where nr_args = length argstys +++{- DataTypeMemberConstructor nm' args mtyargs -> do+ --term_pc stepR (Right $ toVCons nm)+ --term_pc rewVR (Right $ toVCons nm)+ gDataTypeValue (length args) nm -- rules for the operational behaviour of cons+ typeMemberAltCons tyname (maybe tyargs id mtyargs) nm args -- type-membership rule+ astFuncons nm (length args)+ where nm = unpack nm'+-}++typeMemberAltIncl :: Name -> [TPattern] -> FTerm -> RuleBuilder () +typeMemberAltIncl tyname tyargs sort = do+ v1 <- fresh_var+ typats <- mapM tTPattern tyargs + lhs [RF.PVal (adt_type (pack tyname) typats), RF.PVar v1]+ tycheck [RF.TVar v1] (maybeApplyTySeq sort) truePat+ type_member ++ -- TODO extend the `sorts` argument to contain information about the variable+ -- in order to avoid generating sequence-variables where not necessary+typeMemberAltCons :: Name -> [TPattern] -> Name -> [FTerm] -> RuleBuilder ()+typeMemberAltCons tyname tyargs nm sorts = do+ typats <- mapM tTPattern tyargs + patvars <- forM sorts $ \sort -> do+ var <- fresh_var + case mkSort sort of + Nothing -> do+ tycheck [RF.TVar var] (maybeApplyTySeq sort) truePat+ return var+ Just op -> do + add_var_decl_ (gVarDecl var (Just op))+ tycheck [RF.TVar var] (maybeApplyTySeq sort) truePat+ return var+ lhs [RF.PVal (adt_type (pack tyname) typats)+ ,RF.PVal (adt (pack nm) (map RF.PVar patvars))]+ type_member + where mkSort t = case t of + TSortSeq t' op -> Just op+ TSortPower _ _ -> Just StarOp+ TVar var -> case last var of+ '*' -> Just StarOp+ '?' -> Just QuestionMarkOp+ '+' -> Just PlusOp+ _ -> Nothing+ _ -> Nothing ++{-+gDataTypeValue :: Cons -> RuleBuilder ()+gDataTypeValue cs = do -- build axiom+ var <- fresh_var+ lhs (RF.PCons cs [RF.PVar var])+ add_var_decl_ (gVarDecl var (Just StarOp))+ tycheck [RF.TVar var] (tTerm (TName "values")) truePat+ rewrite (RF.TCons "datatype-value" (RF.TVal (fromString cs) : [RF.TVar var])) --rewrite+ strictFCongs cs -- build congruences+-}++strictFCongs :: Cons -> RuleBuilder ()+strictFCongs cs = do+ x_var <- fresh_var+ x_var_rw<- fresh_var+ x_var' <- fresh_var+ lhs (RF.PCons cs [RF.PVar x_var])+ add_var_decl_ (gVarDecl x_var (Just StarOp))+ add_var_decl_ (gVarDecl x_var_rw (Just StarOp))+ add_var_decl_ (gVarDecl x_var' (Just StarOp))+ gOptRewrite [RF.TVar x_var] [RF.PVar x_var_rw]+ premise (RF.TVar x_var_rw) (sRel stepR) (RF.PVar x_var')+ commit (sRel stepR) (RF.TCons cs [RF.TVar x_var'])+ +mkValOpRules :: [RF.Rule]+mkValOpRules = rules+ where IS.Spec new = execRuleBuilder $ mapM_ (uncurry mkrule) + $ assocs (VAL.library :: VAL.Library RF.Term)+ (_,_,_,_,rules) = IS.partition_decls new++ mkrule :: VAL.OP {- String, operation name -} -> VAL.ValueOp t -> RuleBuilder ()+ mkrule nm op = case op of + VAL.NullaryExpr _ -> build $ Just 0 + VAL.UnaryExpr _ -> build $ Just 1+ VAL.BinaryExpr _ -> build $ Just 2+ VAL.TernaryExpr _ -> build $ Just 3+ VAL.NaryExpr _ -> build Nothing+ where+ build marity = do + strictFCongs nm -- congruence rules+ mkAxiom marity -- axiom+ astFuncons nm marity --ast-* funcons+ mkAxiom marity= case marity of + Just arity -> do+ vars <- mapM (const fresh_var) [1..arity]+ mk_strict_lhs nm (map RF.PVar vars)+ vars' <- forM vars $ \var -> do -- termination side conditions+ var' <- fresh_var + gSideCond (SCPatternMatch (TVar var) [PMetaVar var'])+ is_terminating_or_null (RF.TVar var')+ return var'+ rewrite (vop nm (map RF.TVar vars'))+ Nothing -> do+ var <- fresh_var+ lhs (RF.PCons nm [RF.PVar var])+ var' <- fresh_var+ add_var_decl_ (gVarDecl var (Just StarOp))+ add_var_decl_ (gVarDecl var' (Just StarOp))+ gOptRewrite [RF.TVar var] [RF.PVar var'] + is_terminating_or_null (RF.TVar var')+ rewrite (vop nm [RF.TVar var'])+ ++-- meta-programming specific stuff++ctR, dlR, ulR :: RF.RSymb+ctR = "=ct=>"+dlR = "=dl=>"+ulR = "=ul=>"++ctRelRule :: Name -> RuleBuilder ()+ctRelRule nm = do+ var <- fresh_var+ var' <- fresh_var+ lhs (RF.PCons nm [RF.PVar var])+ var_decl var 0 Nothing RF.Longest []+ var_decl var' 0 Nothing RF.Longest []+ premise (RF.TVar var) ctR (RF.PVar var')+ commit ctR (RF.TCons nm [RF.TVar var'])++dlRelRule :: Name -> RuleBuilder ()+dlRelRule nm = do+ var <- fresh_var+ var' <- fresh_var+ lhs (RF.PVal (VAL.ADTVal (pack astv_nm) [RF.PVar var]))+ var_decl var 0 Nothing RF.Longest []+ var_decl var' 0 Nothing RF.Longest []+ premise (RF.TVar var) dlR (RF.PVar var')+ commit dlR (RF.TCons nm [RF.TVar var'])+ where astv_nm = "astv-" ++ nm++ulRelRule :: Name -> RuleBuilder ()+ulRelRule nm = do+ var <- fresh_var+ var' <- fresh_var+ lhs (RF.PCons nm [RF.PVar var])+ var_decl var 0 Nothing RF.Longest []+ var_decl var' 0 Nothing RF.Longest []+ premise (RF.TVar var) ulR (RF.PVar var')+ commit ulR (RF.TCons astv_nm [RF.TVar var'])+ where astv_nm = "astv-" ++ nm ++promoteRule :: Name -> RuleBuilder ()+promoteRule nm = do+ var <- fresh_var+ lhs (RF.PCons nm [RF.PVar var])+ commit ulR (RF.TCons "astv-promote" [RF.TCons nm [RF.TVar var]])++--+-- 1 Generate funcon for funcon named, say "scope", with arity 2+-- > value constructor astv-scope with congruence rules+-- 2 Termination for value constructor+-- 3 Rule that types astv-scope(A:asts,B:asts) as asts+-- 4 astv-scope(A,B) =dl=> scope(Ac, Bc)+-- 5 scope(Ac,Bc) =ul=> astv-scope(A,B)+-- 6 astv-scope(A,B) =ct=> astv-scope(A,B)+-- 7 astv-scope(A,B) =ul=> astv-promote(astv-scope(A,B))+astFuncons :: Name -> Maybe Int -> RuleBuilder()+astFuncons nm marity = return () {-do+ ctRelRule nm+ --term_pc stepR (Right $ "astv-" ++ nm) -- 2+ --term_pc rewR (Right $ "astv-" ++ nm) -- 2+ gDataTypeValue astv_nm -- 1a+ typeMemberAltCons "asts" [] astv_nm [TSortSeq (TName "asts") StarOp] --3+ dlRelRule nm -- 4 + ulRelRule nm -- 5+ ctRelRule astv_nm -- 6+ promoteRule astv_nm+ where astv_nm = "astv-" ++ nm+-}
+ src/Simplify/Utils.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE ScopedTypeVariables #-}++module Simplify.Utils where++import Data.List (sortBy)+import Data.Ord (comparing)++import Control.Applicative+import Control.Monad.Except++import Funcons.EDSL (SeqSortOp(..), Funcons(..), Values(..), string__)+import Funcons.Operations hiding (Values)++import Types.SourceAbstractSyntax (FLiteral(..))++guardM :: MonadError e m => Bool -> e -> m ()+guardM True _ = return ()+guardM False e = throwError e++mergeAssocListsM :: forall k e m a b. (Ord k, MonadError e m) => e -> [(k,a)] -> [(k,b)] -> m [(k,a,b)]+mergeAssocListsM e kas kbs = sequence $ zipWith mergeM (sortBy (comparing fst) kas) (sortBy (comparing fst) kbs)+ where+ mergeM :: (k,a) -> (k,b) -> m (k,a,b)+ mergeM (n1,p) (n2,t) = do guardM (n1 == n2) e+ return (n1,p,t)++traverseEither :: Applicative m => (a -> m c) -> (b -> m d) -> Either a b -> m (Either c d)+traverseEither f _ (Left a) = Left <$> f a+traverseEither _ g (Right b) = Right <$> g b++lookup2 :: Eq a => a -> [(a,b,c)] -> Maybe (b,c)+lookup2 _ [] = Nothing+lookup2 k ((a,b,c):abcs) = if a == k then Just (b,c) else lookup2 a abcs++isSeqVar :: String -> Maybe SeqSortOp+isSeqVar var + | last var == '*' = return StarOp+ | last var == '+' = return PlusOp+ | last var == '?' = return QuestionMarkOp+ | otherwise = Nothing++simplifyLiteral :: FLiteral -> Values +simplifyLiteral lit = case lit of+ FLiteralNat n -> Nat (toInteger n)+ FLiteralAtom char | length char == 1 -> Char (head char)+ | otherwise -> error "atom of size != 1"+ FLiteralString str -> string__ str+ FLiteralFloat f -> Float f+
+ src/Types/Bindings.hs view
@@ -0,0 +1,78 @@+module Types.Bindings where++import Types.SourceAbstractSyntax (MetaVar)++import qualified Types.CoreAbstractSyntax as C++import qualified Data.Set as S++class HasPatVar a where+ pvars :: a -> S.Set MetaVar++instance HasPatVar a => HasPatVar [a] where+ pvars c = S.unions $ fmap pvars c++instance (HasPatVar a, HasPatVar b) => HasPatVar (Either a b) where+ pvars (Left l) = pvars l+ pvars (Right r) = pvars r++instance (HasPatVar a) => HasPatVar (Maybe a) where+ pvars (Just j) = pvars j+ pvars Nothing = S.empty++instance HasPatVar C.FRewriteRule where+ pvars (C.FRewriteRule ps _ ss) = pvars ps `S.union` pvars ss++instance HasPatVar C.FPattern where+ pvars p = case p of + C.PMetaVar v -> S.singleton v+ C.PSeqVar v _ -> S.singleton v+ C.PAnnotated pat _ -> pvars pat+ C.PWildCard -> S.empty + C.PValue vpat -> pvars vpat++instance HasPatVar C.VPattern where+ pvars p = case p of + C.PADT _ ps -> S.unions $ fmap pvars ps+ C.VPWildCard -> S.empty+-- C.PList ps -> S.unions $ fmap pvars ps+ C.VPMetaVar var -> S.singleton var+ C.VPSeqVar var _ -> S.singleton var+ C.VPLit _ -> S.empty+ C.VPAnnotated pat _ -> pvars pat+ C.VPType tpat -> pvars tpat++instance HasPatVar C.TPattern where+ pvars p = case p of+ C.TPWildCard -> S.empty+ C.TPVar var -> S.singleton var+ C.TPSeqVar var _ -> S.singleton var+ C.TPLit _ -> S.empty+ C.TPComputes pat -> pvars pat+ C.TPComputesFrom f t -> pvars f `S.union` pvars t+ C.TPADT _ ps -> S.unions $ fmap pvars ps++instance HasPatVar C.FSideCondition where+ pvars sc = case sc of + C.SCPatternMatch _ p -> pvars p+ _ -> S.empty++instance HasPatVar C.FStepRule where+ pvars (C.FStepRule step scs) = pvars step `S.union` pvars scs++instance HasPatVar C.FStep where+ pvars step = pvars (C.stepSource step) + `S.union` pvars (map snd $ C.stepInheritedEntities step)+ `S.union` pvars (map (\(_,x,_) -> x) $ C.stepMutableEntities step)+ `S.union` pvars (concatMap (\(_,x,_) -> x) $ C.stepInputEntities step)+ `S.union` S.fromList (concatMap (\(_,_,x) -> x) $ C.stepInputEntities step)+ `S.union` pvars (map snd $ C.stepControlEntities step)++instance HasPatVar C.FPremiseStep where+ pvars premise = pvars (C.premiseTarget premise) + `S.union` pvars (map (\(_,_,x) -> x) $ C.premiseMutableEntities premise)+ `S.union` S.fromList (concatMap (\(_,_,x) -> maybe [] (:[]) x) $ C.premiseInputEntities premise)+ `S.union` pvars (map snd $ C.premiseOutputEntities premise)+ `S.union` pvars (map snd $ C.premiseControlEntities premise)++
+ src/Types/ConcreteSyntax.hs view
@@ -0,0 +1,311 @@++module Types.ConcreteSyntax where++import Funcons.EDSL (SeqSortOp(..))++import Data.List (intercalate)++type Name = String++type Var = Maybe String {- wildcard otherwise -}+showVar Nothing = "_"+showVar (Just x) = x++type CBSFile = [CBSSpec]++data CBSSpec = Auxiliary CBSSpec+ | AliasSpec Name Name+ | FunconSpec Name (Maybe Params) Term (Maybe DefRewrite) + | TypeSpec Name (Maybe Params) [Bounds] (Maybe DefRewrite) + | DatatypeSpec Name (Maybe Params) (Maybe Bounds) [DatatypeAlt]+ | EntitySpec Entity + | SyntaxSpec [Prod]+ | LexisSpec [Prod] + | SemanticsSpec Name Var PhraseType (Maybe Params) Term (Maybe DefEqual) {- [Rule] -}+ {- RuleSpec and CommentSpec are not necessary for funcon generation+ however, how to ignore them at parse time without causing ambiguity+ and possible inefficiency? -}+ | RuleSpec Rule+ | OtherwiseSpec Rule+ | CommentSpec [CommentPart]+ | MetaSpec MetaSpec + | MetaVariablesSpec [VarDecl]+ deriving Show++newtype DefRewrite = DefRewrite Term deriving Show+newtype DefEqual = DefEqual Term deriving Show++data VarDecl = VarDeclSubType String Term+ | VarDeclType String Term+ deriving Show++data MetaSpec = HS_Imports String {- to be directly copied into a HS module -}+ deriving Show++type Params = [Param]+data Param = Param Var (Maybe Bounds) + deriving Show++data Bounds = InType Type+ | Sub Type+ | Sup Type+ deriving Show++data DatatypeAlt = Cons Name (Maybe Params)+ | Inj Var Type + | AltDots+ deriving Show++type Type = Term+showType = showConcreteTerm++data Term = TermConst Const + | TermVar Var+ | TermDots+ | TermName Name+ | NameApp Name Term+ | VarApp Var Term+ | Typed Term Type+ | Computes Type+ | ComputesFrom Type Type+ | TermPostfix Type SeqSortOp + | TermSequence [Term] -- wrapped inside 'group'+ | TermComplement Term+ | TermUnion Type Type+ | TermInter Type Type+ | TermTuple [Term]+ | TermList [Term]+ | TermSet [Term]+ | TermMap [Maybe (Term, Term)] --nothing when "..."+ | TermPower Term Term+ -- semantic translation+ | SemanticsApp Name PhraseTerm (Maybe Term)+ deriving Show++-- | Smart constructor to replace `TermTuple` that prevents singleton tuples+termTuple :: [Term] -> Term+termTuple [t] = t+termTuple ts = TermTuple ts++termName :: Term -> Name+termName (NameApp nm _) = nm+termName (TermName nm) = nm+termName t = error ("termName: " ++ show t)++termArgs :: Term -> Maybe [Term]+termArgs (NameApp nm arg) = case arg of+ TermTuple [] -> Nothing+ TermTuple args -> Just args+ _ -> Just [arg]+termArgs _ = Nothing+ +data Const = ConstAtom String+ | ConstString String+ | ConstNat Int+ | ConstFloat Double + deriving Show++showConst c = case c of + ConstAtom str -> "'" ++ str ++ "'"+ ConstString str -> show str+ ConstNat i -> show i+ ConstFloat d -> show d++showConcreteTerm :: Term -> String+showConcreteTerm t = case t of + TermConst c -> showConst c+ TermVar x -> showVar x+ TermDots -> "..."+ TermComplement t2 -> "~" ++ showConcreteTerm t2+ TermName n -> n+ NameApp n t2 -> n ++ showConcreteTerm t2+ VarApp x t2 -> showVar x ++ showConcreteTerm t2+ Typed t2 ty -> showConcreteTerm t2 ++ ":" ++ showType ty+ Computes ty -> "=>" ++ showType ty+ ComputesFrom fty tty -> showType fty ++ "=>" ++ showType tty+ TermPostfix ty op -> showType ty ++ show op+ TermSequence seq -> intercalate "," (map showConcreteTerm seq)+ TermUnion t1 t2 -> showConcreteTerm t1 ++ "|" ++ showConcreteTerm t2+ TermInter t1 t2 -> showConcreteTerm t1 ++ "&" ++ showConcreteTerm t2+ TermTuple ts -> "(" ++ showConcreteTerm (TermSequence ts) ++ ")"+ TermList ts -> "[" ++ showConcreteTerm (TermSequence ts) ++ "]"+ TermSet ts -> "{" ++ showConcreteTerm (TermSequence ts) ++ "}"+ TermMap mkvs -> "{" ++ intercalate "," (map showMKV mkvs) ++ "}"+ TermPower t1 t2 -> showConcreteTerm t1 ++ "^" ++ showConcreteTerm t2+ SemanticsApp nm sxs Nothing -> nm ++ "[[" ++ concatMap showPhraseTerm sxs ++ "]]"+ SemanticsApp nm sxs (Just ty2) -> showConcreteTerm (SemanticsApp nm sxs Nothing) ++ + "(" ++ showConcreteTerm ty2 ++ ")" + where+ showMKV mkv = case mkv of + Nothing -> "..."+ Just (k, v) -> showConcreteTerm k ++ "|->" ++ showConcreteTerm v++data Rule = Inference [Premise] Conclusion+ -- semantics+ | Desugar PhrasePatt PhraseType PhraseTerm+ | Semantics Name PhrasePatt (Maybe Term) [Term]+ deriving Show++type PhrasePatt = [WordPatt]+type PhraseTerm = [WordTerm]+data PhraseType = PTSynName Name+ | PTAtom Atom + | PTRange Atom Atom+ | PTPostfix PhraseType SeqSortOp+ | PTComplement PhraseType + | PTSeq PhraseType PhraseType+ | PTNoLayout PhraseType PhraseType+ | PTUnion PhraseType PhraseType+ | PTGroup (Maybe PhraseType)+ deriving (Show)++data WordTerm = WTVar Var + | WTAtom String+ | WTGroup [WordTerm]+ deriving (Show)++data Premise = PremDynamic (Maybe Context) State Dynamic State+ | PremTyping (Maybe Context) State Term+ | PremStatic (Maybe Context) State Term Static State+ | PremRewrite Term Term+ | PremEquality Term Term+ | PremInequality Term Term+ | PremSubtype Term Term+ deriving (Show)++premSource :: Premise -> Term +premSource (PremRewrite t1 _) = t1+premSource (PremStatic _ s _ _ _) = stateTerm s+premSource (PremTyping _ s _) = stateTerm s+premSource (PremDynamic _ s _ _) = stateTerm s+premSource (PremEquality t _) = t+premSource (PremInequality t _) = t+premSource (PremSubtype t _) = t++premTarget :: Premise -> Term +premTarget (PremRewrite _ t) = t+premTarget (PremStatic _ _ _ _ s) = stateTerm s+premTarget (PremTyping _ _ t) = t -- type+premTarget (PremDynamic _ _ _ s) = stateTerm s+premTarget (PremEquality _ t) = t+premTarget (PremInequality _ t) = t+premTarget (PremSubtype _ t) = t++data Conclusion = ConcDynamic (Maybe Context) State Dynamic State+ | ConcTyping (Maybe Context) State Term+ | ConcStatic (Maybe Context) State Term Static State+ | ConcRewrite Term Term+ deriving (Show)++concSource :: Conclusion -> Term +concSource (ConcRewrite t1 _) = t1+concSource (ConcStatic _ s _ _ _) = stateTerm s+concSource (ConcTyping _ s _) = stateTerm s+concSource (ConcDynamic _ s _ _) = stateTerm s++concTarget :: Conclusion -> Term +concTarget (ConcRewrite _ t) = t+concTarget (ConcStatic _ _ _ _ s) = stateTerm s+concTarget (ConcTyping _ _ t) = t -- type+concTarget (ConcDynamic _ _ _ s) = stateTerm s++data State = StateExplicit Term [EntTerm]+ | StateImplicit Term+ deriving (Show)++stateTerm :: State -> Term+stateTerm (StateExplicit t _) = t+stateTerm (StateImplicit t) = t++stateEnts :: State -> [EntTerm]+stateEnts (StateExplicit _ es) = es+stateEnts (StateImplicit _) = []++data Dynamic = DynamicExplicit [PolarEntTerm] (Maybe Int) -- premise id+ | DynamicImplicit (Maybe Int) --premise id+ | DynamicComposition Dynamic Dynamic+ deriving Show++dynamicEnts :: Dynamic -> [PolarEntTerm]+dynamicEnts (DynamicExplicit ps _) = ps+dynamicEnts _ = []++data Static = StaticExplicit [PolarEntTerm]+ | StaticImplicit + deriving Show++data WordPatt = WPVar Var + | WPAtom String+ | WPGroup [WordPatt]+ | WPUnion Atom [Atom]+ deriving (Show)+ +type Atom = String++showPhraseTerm :: WordTerm -> String+showPhraseTerm wt = case wt of + WTVar x -> showVar x+ WTAtom a -> "'" ++ a ++ "'"+ WTGroup wts -> "(" ++ concatMap showPhraseTerm wts ++ ")" ++data Entity = EntContextual Ent Arrow+ | EntMutable Ent Arrow Ent+ | EntObservable EntArrow+ deriving Show++data Arrow = ADynamic | AStatic + deriving Show+data EntArrow = EADynamic Ent | EAStatic Ent+ deriving Show++type EntTerm = (Name, Term)+type PolarEntTerm = (Name, Term, Maybe Polarity)++data Ent = EntVarStem VarStem (Maybe Polarity)+ | EntName Name (Maybe Polarity) Var Term+ deriving Show+ +data Polarity = In | Out + deriving (Show, Enum) ++data Context = Context [EntTerm] deriving Show++contextEnts :: Maybe Context -> [EntTerm]+contextEnts = maybe [] (\(Context es) -> es)++data Pred = PredType Term+ | PredSubType Term+ deriving Show++data CommentPart = Ordinary String+ | Asterisk+ | At String+ | CommentTerm [Term]+ | CommentPremise Premise+ | SpecInComment CBSSpec+ deriving Show+++showComments :: [CommentPart] -> String+showComments = concatMap showComment++showComment :: CommentPart -> String+showComment (Ordinary c) = c+showComment (Asterisk) = "*"+showComment (At sect) = "@" ++ sect+-- TODO should use showFuncons, but requires static substitute + simplification+showComment (CommentTerm t) = "`" ++ show t ++ "`"+showComment c = "<missing comment-part>"+++data Prod = Prod [VarStem] SynName PhraseType -- lists of alternatives+ | SDFComment [CommentPart]+ deriving Show++type VarStem = String+type SynName = String+data VarSynName = VarName VarStem SynName + | SynName String+ deriving Show++
+ src/Types/CoreAbstractSyntax.hs view
@@ -0,0 +1,162 @@+{-# LANGUAGE LambdaCase, OverloadedStrings #-}++-- This is a simplified version of SourceAbstractSyntax.+-- Information not needed for code generation has been discarded.+module Types.CoreAbstractSyntax (+ -- copies of source+ CBSFile(..), CBSSpec(..), EntitySpec(..),FunconSpec(..),FSig(..),FStep(..),+ FPremiseStep(..), FSideCondition(..), DataTypeSpec(..), DataTypeAlt(..),+ FSort,+ -- defined here+ FStepRule(..), Strictness(..), FRewriteRule(..),+ isStrict, isSeqVarSort, funconIsStrict, funconIsNullary, CommentPart(..), + ConsSpec(..),CSig(..),+ -- defined in the interpreter+ FTerm(..),TypeEnv, FPattern(..), VPattern(..), TPattern(..),TyAssoc(..),+ )where++import Funcons.EDSL (FTerm(..), FPattern(..), VPattern(..), TPattern(..), TypeEnv(..), TyAssoc(..), HasTypeVar(..))++import Types.ConcreteSyntax (MetaSpec(..), Term, Premise)+import Types.SourceAbstractSyntax hiding (CBSFile,CBSSpec,EntitySpec,FunconSpec,FSig(..),FStep,FPremiseStep,FSideCondition,DataTypeSpec(..), FTerm(..), FPattern(..),FSort(..),TypeEnv, TyAssoc(..), DataTypeAlt(..),FPattern(..), CommentPart(..))++data CBSFile = CBSFile {cbs :: [CBSSpec], env :: TypeEnv, aliases :: AliasMap}++data CBSSpec = FunconSpec FunconSpec+ | DataTypeSpec DataTypeSpec+ | EntitySpec EntitySpec+ | MetaSpec MetaSpec+ | ConsSpec ConsSpec+ deriving (Show)++data EntitySpec = InheritedSpec Name FTerm+ | MutableSpec Name FTerm+ | InputSpec Name+ | OutputSpec Name+ | ControlSpec Name+ deriving (Show)++data FunconSpec = FRules Name FSig (Maybe [CommentPart]) [FRewriteRule] [FStepRule]+ deriving (Show)++data ConsSpec = ValCons Name -- constructor name + CSig -- datatype or type constructor?+ [FSort] -- the types the arguments should have + Name -- name of type for which it constructs values+ [TPattern] -- type params for type (required for GADTs)+ deriving (Show)++data CommentPart = Ordinary String+ | Asterisk+ | At String+ | CommentTerm [Term]+ | CommentPremise Premise+ | SpecInComment CBSSpec+ deriving Show++data FSig = FStrict -- fully strict, possibly variadic+ | FLazy -- fully non-strict, possibly variadic+ | FPartiallyLazy [Strictness] -- mixed strict, non-variadic+ (Maybe Strictness) -- zero or more args with this strictness+ | FNullary -- no arguments+ deriving (Eq,Ord,Show)++data CSig = DataTypeCons+ | TypeCons FSig + deriving (Show)++funconIsStrict :: FSig -> Bool+funconIsStrict = \case FStrict -> True+ _ -> False++funconIsNullary :: FSig -> Bool+funconIsNullary = \case FNullary -> True+ _ -> False++data Strictness = Strict | Lazy+ deriving (Eq,Ord,Show)++isStrict Strict = True+isStrict Lazy = False++data FRewriteRule = FRewriteRule [FPattern] (Maybe FTerm) [FSideCondition]+ deriving (Eq,Ord,Show)++data FStepRule = FStepRule FStep [Either FPremiseStep FSideCondition]+ deriving (Eq,Ord,Show)++data FStep = FStep+ { stepSource :: [FPattern]+ , stepTarget :: FTerm+ , stepInheritedEntities :: [(Name,[FPattern])]+ , stepMutableEntities :: [(Name,FPattern,FTerm)]+ , stepInputEntities :: [(Name,[FPattern],[MetaVar])]+ , stepOutputEntities :: [(Name,FTerm)]+ , stepControlEntities :: [(Name,Maybe FPattern)]+ }+ deriving (Eq,Ord,Show)++data FPremiseStep = FPremiseStep+ { premiseSource :: FTerm+ , premiseTarget :: [FPattern]+ , premiseInheritedEntities :: [(Name,FTerm)]+ , premiseMutableEntities :: [(Name,FTerm,FPattern)]+ , premiseInputEntities :: [(Name,[FTerm],Maybe MetaVar)]+ , premiseOutputEntities :: [(Name,FPattern)]+ , premiseControlEntities :: [(Name,Maybe FPattern)]+ }+ deriving (Eq,Ord,Show)++data FSideCondition = SCEquality FTerm FTerm+ | SCInequality FTerm FTerm+ | SCPatternMatch FTerm [FPattern]+ | SCIsInSort FTerm FSort+ | SCNotInSort FTerm FSort+ deriving (Eq,Ord,Show)++type FSort = FTerm++termComputes :: FSort -> Bool+termComputes (TSortComputes _) = True+termComputes (TSortComputesFrom _ _) = True+termComputes _ = False++isSeqVarSort :: FSort -> Bool+isSeqVarSort (TVar var) = seqChar (last var)+ where seqChar c = case c of '*' -> True+ '?' -> True+ '+' -> True+ _ -> False+isSeqVarSort _ = False++data DataTypeSpec = DataTypeDecl Name [TPattern] [DataTypeAlt]+ deriving (Show)++data DataTypeAlt = DataTypeInclusion FSort+ deriving (Eq,Ord,Show)++{-+data FPattern = PTuple [FPattern]+ | PList [FPattern]+ | PAnnotated FPattern FSort+ | PADT ADTConstructor [FPattern]+ | PAny+ | PLit FLiteral+ | PMetaVar MetaVar+ | PSeqMetaVar MetaVar SeqSortOp -- Note: the MetaVar should also contain the operator suffix+ deriving (Eq,Ord,Show)+-}+-------------------------------------------------++{-+instance HasTypeVar FPattern where+ subsTypeVarWildcard mt env pat = case pat of+ PAnnotated p t -> PAnnotated (subsTypeVarWildcard mt env p) (subsTypeVarWildcard mt env t)+ PADT n pats -> PADT n (map (subsTypeVarWildcard mt env) pats)+ PTuple pats -> PTuple (map (subsTypeVarWildcard mt env) pats)+ PList pats -> PList (map (subsTypeVarWildcard mt env) pats)+ PMetaVar var -> PMetaVar var+ PSeqMetaVar var op -> PSeqMetaVar var op+ PLit v -> PLit v+ PAny -> PAny+-}
+ src/Types/FunconModule.hs view
@@ -0,0 +1,68 @@++module Types.FunconModule where++import Funcons.EDSL(DataTypeMembers(..))+import Types.SourceAbstractSyntax (Name, MetaVar, AliasMap)+import Types.CoreAbstractSyntax (FSig(..), EntitySpec(..), FPattern(..)+ , FTerm(..), FSideCondition, CommentPart(..), TypeEnv)+import Types.TargetAbstractSyntax (InputAccess)++data FunconModule = FunconModule { funcons :: [FunconSpec]+ , entities :: [EntitySpec]+ , datatypes :: [DataTypeMembers]+ , env :: TypeEnv+ , aliases :: AliasMap }++-- A funcon:+-- * Has a name+-- * Is either strict, lazy or partially lazy+-- * Has a number of rewrite rules (each a sequence of rewrite statements)+-- * Has a number of step rules (each a sequence of step statements)+data FunconSpec = FunconSpec Name FSig (Maybe [CommentPart]) [[FRewriteStmt]] [[FStepStmt]]++-- | Representation of a variable in the target language (Haskell/Java)+type TargetVar = String++fargs_var, env_var, empty_env :: TargetVar +empty_env = "emptyEnv"+fargs_var = "fargs"+env_var = "env"++-- an entity value is either:+-- * read : just ask the monad to get the value+-- * written : just insert the value into the monad+-- * scoped : execute further computation with given entity value+-- * received : what is the value after computation?+data FStepStmt + = FRewriteStmt FRewriteStmt -- subtyping+ | ReadInherited Name [FPattern]+ | ScopeInherited Name FTerm FStepStmt --set inh for the next stmt+ | WriteMutable Name FTerm + | ReadMutable Name FPattern+ | ReceiveControl [Name] FStepStmt+ | ReadControl Name (Maybe FPattern)+ | WriteControl Name (Maybe FTerm)+ | ReadDownControl Name (Maybe FPattern)+ | ScopeDownControl Name (Maybe FTerm) FStepStmt + | ReceiveOutput Name FPattern FStepStmt+ | WriteOutput Name FTerm + | ReadInput Name [FPattern]+ | ScopeInput Name [FTerm] InputAccess{-exact?-} FStepStmt+ | PremiseBlock FStepStmt -- groups statements particular to a premise+ | Premise FTerm [FPattern]+ | StepTarget FTerm + | SBranches [[FStepStmt]]+ deriving (Ord, Eq)++-- subtype of FStepStmt+-- define two evaluation, 1 producing code for rewrite rules, 1 for steps +-- (applying lifted version of helpers)+data FRewriteStmt + = ArgsPattern TargetVar [FPattern] -- match a sequence of funcons+ | EnvStore MetaVar FTerm -- bind var to term in the meta-environment+ | EnvRewrite MetaVar -- rewrite var inside the meta-environment+ | CheckSideCondition FSideCondition+ | RewriteTarget FTerm + | RBranches [[FRewriteStmt]]+ deriving (Ord, Eq)+
+ src/Types/SourceAbstractSyntax.hs view
@@ -0,0 +1,183 @@+module Types.SourceAbstractSyntax (+ -- defined here+ CBSFile(..), CBSSpec(..), TypeSynonymSpec(..), DataTypeSpec(..),+ EntitySpec(..), FunconSpec(..), FRule(..), FSideCondition(..),+ FSig(..), FParam(..), ParamPattern(..), Name, FStep(..), FPremiseStep(..),+ FPattern(..), FLiteral(..), ADTConstructor, + FSort, TypeEnv, TyAssoc(..), AliasMap, my_aliases,+ MetaVar, FTerm(..), DataTypeAlt(..),+ CommentPart(..), isStrictParam, isStrictSort, termArgs, isVariadic,+ -- defined in Funcons.EDSL+ SeqSortOp(..),+ ) where++import Funcons.EDSL (SeqSortOp(..))+import Types.ConcreteSyntax (MetaSpec(..), Term, Premise)++import qualified Data.Map as M++type Name = String++data CBSFile = CBSFile {cbs :: [CBSSpec], env :: TypeEnv, aliases :: AliasMap }++type TypeEnv = M.Map MetaVar TyAssoc+data TyAssoc = ElemOf FSort | SubTyOf FSort +type AliasMap = M.Map Name [Name]++my_aliases :: Name -> AliasMap -> [Name]+my_aliases nm als = my_aliases' [] nm als+ where my_aliases' ctx nm als + | nm `elem` ctx = error "cyclic aliases"+ | otherwise = nm : concatMap (\n -> my_aliases' (nm:ctx) n als) + (maybe [] id (M.lookup nm als))++data CBSSpec = FunconSpec FunconSpec+ | TypeSynonymSpec TypeSynonymSpec+ | DataTypeSpec DataTypeSpec+ | TypeSpec DataTypeSpec+ | EntitySpec EntitySpec+ | MetaSpec MetaSpec+ deriving (Show)++data TypeSynonymSpec = TypeSynonymDecl Name [FParam] FSort+ deriving (Show)++data DataTypeSpec = DataTypeDecl Name [FParam] [DataTypeAlt]+ deriving (Show)++data DataTypeAlt = DataTypeInclusion FSort+ | DataTypeConstructor Name [FSort]+ deriving (Eq,Ord,Show)++data EntitySpec = InheritedSpec (Name,FTerm,FSort)+ | MutableSpec (Name,FTerm,FSort) (Name,FPattern,FSort)+ | InputSpec (Name,FPattern,FSort)+ | OutputSpec (Name,FPattern,FSort)+ | ControlSpec (Name,FSort)+ deriving (Show)++data FunconSpec = FAbbrv FSig (Maybe FTerm) {- nothing if := ... -}+ | FRules FSig [FRule]+ deriving (Show)++data FRule = FRuleRewrite Name (Maybe [FPattern]) (Maybe FTerm) [FSideCondition]+ | FRuleStep Name FStep [Either FPremiseStep FSideCondition]+ deriving (Eq,Ord,Show)++data FSideCondition = SCEquality FTerm FTerm+ | SCInequality FTerm FTerm+ | SCPatternMatch FTerm [FPattern]+ | SCIsInSort FTerm FSort+ deriving (Eq,Ord,Show)++data FSig = FSig+ { sigName :: Name,+ sigParams :: [FParam],+ sigSort :: FSort,+ sigDoc :: Maybe [CommentPart] + }+ deriving (Show)++data CommentPart = Ordinary String+ | Asterisk+ | At String+ | CommentTerm [Term]+ | CommentPremise Premise + | SpecInComment CBSSpec+ deriving Show++++type FParam = (ParamPattern, Maybe FSort)++isStrictParam :: FParam -> Bool+isStrictParam param@(_,sorts) = maybe False isStrictSort sorts++isStrictSort :: FSort -> Bool+isStrictSort sort = case sort of+ TSortSeq (TTuple [t]) _ -> isStrictSort t+ TSortSeq t _ -> isStrictSort t+ TSortComputes _ -> False+ TSortComputesFrom _ _ -> False+ _ -> True++isVariadic :: FParam -> Bool+isVariadic (_, Just (TSortSeq _ _)) = True+isVariadic _ = False++data ParamPattern = PPMetaVar MetaVar+ | PPSeqMetaVar MetaVar SeqSortOp+ | PPAny+ deriving (Eq,Ord,Show)++data FStep = FStep+ { stepSource :: Maybe [FPattern]+ , stepTarget :: FTerm+ , stepInheritedEntities :: [(Name,[FPattern])]+ , stepMutableEntities :: ([(Name,FPattern)],[(Name,FTerm)])+ , stepInputEntities :: [(Name,FPattern)]+ , stepOutputEntities :: [(Name,FTerm)]+ , stepControlEntities :: [(Name,FPattern)]+ }+ deriving (Eq,Ord,Show)++data FPremiseStep = FPremiseStep+ { premiseSource :: FTerm+ , premiseTarget :: [FPattern]+ , premiseInheritedEntities :: [(Name,FTerm)]+ , premiseMutableEntities :: ([(Name,FTerm)],[(Name,FPattern)])+ , premiseInputEntities :: [(Name,FTerm)]+ , premiseOutputEntities :: [(Name,FPattern)]+ , premiseControlEntities :: [(Name,FPattern)]+ }+ deriving (Eq,Ord,Show)++data FPattern = PSeq [FPattern]+ | PList [FPattern]+ | PAnnotated FPattern FSort+ | PADT ADTConstructor [FPattern]+ | PAny+ | PLit FLiteral+ | PMetaVar MetaVar+ | PSeqMetaVar MetaVar SeqSortOp -- Note: the MetaVar should also contain the operator suffix+ deriving (Eq,Ord,Show)++data FLiteral = FLiteralNat Int+ | FLiteralFloat Double + | FLiteralString String+ | FLiteralAtom String+ deriving (Eq,Ord,Show)++type ADTConstructor = String+++type FSort = FTerm++type MetaVar = String++data FTerm = TMetaVar MetaVar+ | TLiteral FLiteral+ | TName Name+ | TApp Name [FTerm]+ | TTuple [FTerm]+ | TList [FTerm]+ | TSet [FTerm]+ | TMap [FTerm]+ | TBinding FTerm FTerm+ | TSortPower FTerm FTerm+ | TSortUnion FTerm FTerm+ | TSortInter FTerm FTerm+ | TSortComplement FTerm+ | TSortSeq FTerm SeqSortOp+ | TSortComputes FTerm+ | TSortComputesFrom FTerm FTerm+ | TAny+ deriving (Eq,Ord,Show)++termArgs :: FTerm -> Maybe [FTerm]+termArgs t = case t of + TName _ -> Nothing+ TApp _ ts -> Just ts+ _ -> Nothing++-------------------------------------------------
+ src/Types/TargetAbstractSyntax.hs view
@@ -0,0 +1,129 @@+-- This is a version of CoreAbstractSyntax+-- with some modifications helpful towards code-generation.+-- Information not needed for code generation has been discarded.+module Types.TargetAbstractSyntax + (module Types.TargetAbstractSyntax+ ,TPattern(..), FCT.FPattern(..), VPattern(..)) where++import Types.ConcreteSyntax (MetaSpec)+import Types.SourceAbstractSyntax hiding (CBSFile(..),CBSSpec(..),EntitySpec,FunconSpec,FSig,FStep(..),FPremiseStep(..),FSideCondition(..),DataTypeAlt(..), DataTypeSpec(..),FTerm(..),FPattern(..), CommentPart(..),cbs, FValSort, TypeEnv)+import Types.CoreAbstractSyntax hiding (CBSSpec(..),FunconSpec(..),FStepRule(..),FRewriteRule(..),FStep(..),FPremiseStep(..),CBSFile(..),cbs)+import Funcons.EDSL (TypeEnv, HasTypeVar(..), TPattern(..), VPattern(..))+import qualified Funcons.EDSL as FCT++data CBSFile = CBSFile {cbs :: [CBSSpec], env :: TypeEnv, aliases :: AliasMap}++data CBSSpec = FunconSpec FunconSpec+ | DataTypeSpec DataTypeSpec+ | EntitySpec EntitySpec+ | MetaSpec MetaSpec+ | ConsSpec ConsSpec + deriving (Show)++funcons :: CBSFile -> [FunconSpec]+entities :: CBSFile -> [EntitySpec]+datatypes :: CBSFile -> [DataTypeSpec]+metadata :: CBSFile -> [MetaSpec]+constructors :: CBSFile -> [ConsSpec]++funcons = foldr op [] . cbs+ where op (FunconSpec f) xs = (f:xs)+ op _ xs = xs+entities = foldr op [] . cbs+ where op (EntitySpec e) xs = e:xs+ op _ xs = xs+datatypes = foldr op [] . cbs+ where op (DataTypeSpec d) xs = d:xs+ op _ xs = xs+metadata = foldr op [] . cbs+ where op (MetaSpec f) xs = f:xs + op _ xs = xs+constructors = foldr op [] . cbs+ where op (ConsSpec f) xs = f:xs + op _ xs = xs++doToFuncons :: (FunconSpec -> FunconSpec) -> CBSFile -> CBSFile+doToFuncons f file = file{cbs = map op $ cbs file}+ where op (FunconSpec spec) = FunconSpec (f spec)+ op spec = spec++-- TODO migrate commentpart to meta-data?+data FunconSpec = FRules Name FSig (Maybe [CommentPart]) [FRewriteRule] [FStepRule]+ deriving (Show)++data FStepRule = FStepRule FStep [Either FPremiseStep FSideCondition]+ deriving (Show)++data FRewriteRule = FRewriteRule [FPattern] (Maybe FTerm) [FSideCondition]+ deriving (Show)++data FStep = FStep+ { stepSource :: [FPattern]+ , stepTarget :: FTerm+ , stepInheritedEntities :: [(Name,[FPattern])]+ , stepMutableEntities :: [(Name,FPattern,FTerm)]+ , stepInputEntities :: [(Name,[FPattern])]+ , stepOutputEntities :: [(Name,FTerm)]+ , stepControlEntities :: [(Name,Maybe FPattern)]+ }+ deriving (Eq,Ord,Show)++data FPremiseStep = FPremiseStep+ { premiseSource :: FTerm+ , premiseTarget :: [FPattern]+ , premiseInheritedEntities :: [(Name,FTerm)]+ , premiseMutableEntities :: [(Name,FTerm,FPattern)]+ , premiseInputEntities :: [(Name,[FTerm],InputAccess)]+ , premiseOutputEntities :: [(Name,FPattern)]+ , premiseControlEntities :: [(Name,Maybe FPattern)]+ }+ deriving (Eq,Ord,Show)++data InputAccess = ExactInput | ExtraInput+ deriving (Eq,Ord,Show)++instance HasTypeVar FSideCondition where+ subsTypeVarWildcard mt env sc = case sc of + SCIsInSort t ty -> SCIsInSort t (subsTypeVarWildcard mt env ty)+ SCNotInSort t ty -> SCNotInSort t (subsTypeVarWildcard mt env ty)+ SCPatternMatch t pat -> SCPatternMatch t (subsTypeVarWildcard mt env pat)+ SCEquality t1 t2 -> SCEquality t1 t2+ SCInequality t1 t2 -> SCInequality t1 t2+ +instance (HasTypeVar a, HasTypeVar b) => HasTypeVar (Either a b) where + subsTypeVarWildcard mt env (Left l) = Left $ subsTypeVarWildcard mt env l+ subsTypeVarWildcard mt env (Right r) = Right $ subsTypeVarWildcard mt env r++instance (HasTypeVar a) => HasTypeVar (Maybe a) where+ subsTypeVarWildcard mt env = fmap (subsTypeVarWildcard mt env)+instance (HasTypeVar a) => HasTypeVar [a] where+ subsTypeVarWildcard mt env = fmap (subsTypeVarWildcard mt env)++instance HasTypeVar FStepRule where+ subsTypeVarWildcard mt env (FStepRule step scs) = FStepRule (subsTypeVarWildcard mt env step) (subsTypeVarWildcard mt env scs)++instance HasTypeVar FRewriteRule where+ subsTypeVarWildcard mt env (FRewriteRule pats t scs) = FRewriteRule (subsTypeVarWildcard mt env pats) (subsTypeVarWildcard mt env t) (subsTypeVarWildcard mt env scs)++instance HasTypeVar FStep where+ subsTypeVarWildcard mt env step = step {stepSource = subsTypeVarWildcard mt env (stepSource step)+ ,stepInheritedEntities = map (subs2of2 env) (stepInheritedEntities step)+ ,stepMutableEntities = map (subs2of3 env) (stepMutableEntities step)+ ,stepInputEntities = map (subs2of2 env) (stepInputEntities step)+ ,stepControlEntities = map (subs2of2 env) (stepControlEntities step)}++instance HasTypeVar FPremiseStep where+ subsTypeVarWildcard mt env step = step {premiseTarget = subsTypeVarWildcard mt env (premiseTarget step)+ ,premiseMutableEntities = map (subs3of3 env) (premiseMutableEntities step)+ ,premiseOutputEntities = map (subs2of2 env) (premiseOutputEntities step)+ ,premiseControlEntities = map (subs2of2 env) (premiseControlEntities step)}++subs2of2 :: HasTypeVar b => TypeEnv -> (a, b) -> (a, b)+subs2of2 env (a,b) = (a, subsTypeVar env b)++subs2of3 :: HasTypeVar b => TypeEnv -> (a,b,c) -> (a,b,c)+subs2of3 env (a,b,c) = (a, subsTypeVar env b,c)++subs3of3 :: HasTypeVar c => TypeEnv -> (a,b,c) -> (a,b,c)+subs3of3 env (a,b,c) = (a, b, subsTypeVar env c)+