Copyright : (c) Till Mossakowski, Uni Bremen 2004-2005
Maintainer : hausmann@informatik.uni-bremen.de
static analysis for CoCASL
type CSign = Sign C_FORMULA CoCASLSign
instance TermExtension C_FORMULA where
freeVarsOfExt sign cf = case cf of
BoxOrDiamond _ _ f _ -> freeVars sign f
:: (BASIC_SPEC C_BASIC_ITEM C_SIG_ITEM C_FORMULA,
Sign C_FORMULA CoCASLSign, GlobalAnnos)
-> Result (BASIC_SPEC C_BASIC_ITEM C_SIG_ITEM C_FORMULA,
ExtSign (Sign C_FORMULA CoCASLSign) Symbol,
[Named (FORMULA C_FORMULA)])
basicAnalysis minExpForm ana_C_BASIC_ITEM ana_C_SIG_ITEM ana_CMix
ana_CMix :: Mix C_BASIC_ITEM C_SIG_ITEM C_FORMULA CoCASLSign
{ getBaseIds = ids_C_BASIC_ITEM
, getSigIds = ids_C_SIG_ITEM
, getExtIds = \ e -> let c = constructors e in
mkIdSets (opMapConsts c) (nonConsts c)
Set.empty , putParen = mapC_FORMULA
, mixResolve = resolveC_FORMULA
ids_C_BASIC_ITEM :: C_BASIC_ITEM -> IdSets
ids_C_BASIC_ITEM ci = case ci of
(unite2 $ map (ids_CODATATYPE_DECL . item) al,
Set.empty)
CoSort_gen al _ -> unite $ map (ids_SIG_ITEMS ids_C_SIG_ITEM . item) al
ids_C_SIG_ITEM :: C_SIG_ITEM -> IdSets
ids_C_SIG_ITEM (CoDatatype_items al _) =
(unite2 $ map (ids_CODATATYPE_DECL . item) al,
Set.empty)
ids_CODATATYPE_DECL (CoDatatype_decl _ al _) =
unite2 $ map (ids_COALTERNATIVE . item) al
ids_COALTERNATIVE a = let e =
Set.empty in case a of
if null cs then (s, e) else
ids_COCOMPONENTS :: COCOMPONENTS ->
Set.Set Id
data CoRecord a b c d = CoRecord
{ foldBoxOrDiamond :: C_FORMULA -> Bool -> d -> a -> Range -> c
, foldCoSort_gen_ax :: C_FORMULA -> [SORT] -> [OP_SYMB] -> Bool -> c
, foldTerm_mod :: MODALITY -> b -> d
, foldSimple_mod :: MODALITY -> SIMPLE_ID -> d
foldC_Formula :: Record C_FORMULA a b -> CoRecord a b c d -> C_FORMULA -> c
foldC_Formula r cr c = case c of
foldBoxOrDiamond cr c b (foldModality r cr m) (foldFormula r f) ps
CoSort_gen_ax s o b -> foldCoSort_gen_ax cr c s o b
foldModality :: Record C_FORMULA a b -> CoRecord a b c d -> MODALITY -> d
foldModality r cr m = case m of
Term_mod t -> foldTerm_mod cr m $ foldTerm r t
Simple_mod i -> foldSimple_mod cr m i
mapCoRecord :: CoRecord (FORMULA C_FORMULA) (TERM C_FORMULA) C_FORMULA MODALITY
{ foldBoxOrDiamond = const BoxOrDiamond
, foldCoSort_gen_ax = const CoSort_gen_ax
, foldTerm_mod = const Term_mod
, foldSimple_mod = const Simple_mod
constCoRecord :: ([a] -> a) -> a -> CoRecord a a a a
constCoRecord jn c = CoRecord
{ foldBoxOrDiamond = \ _ _ m f _ -> jn [m, f]
, foldCoSort_gen_ax = \ _ _ _ _ -> c
, foldTerm_mod = \ _ t -> t
, foldSimple_mod = \ _ _ -> c
mapC_FORMULA :: C_FORMULA -> C_FORMULA
mapC_FORMULA = foldC_Formula (mkMixfixRecord mapC_FORMULA) mapCoRecord
resolveMODALITY :: MixResolve MODALITY
resolveMODALITY ga ids m = case m of
fmap Term_mod $ resolveMixTrm mapC_FORMULA resolveC_FORMULA ga ids t
resolveC_FORMULA :: MixResolve C_FORMULA
resolveC_FORMULA ga ids cf = case cf of
BoxOrDiamond b m f ps -> do
nm <- resolveMODALITY ga ids m
nf <- resolveMixFrm mapC_FORMULA resolveC_FORMULA ga ids f
return $ BoxOrDiamond b nm nf ps
_ -> error "resolveC_FORMULA"
minExpForm :: Min C_FORMULA CoCASLSign
minMod md ps = case md of
Simple_mod i -> minMod (Term_mod (Mixfix_token i)) ps
t2 <- oneExpTerm minExpForm s t
else Result [mkDiag Error
++ showId srt "' for term") t ]
then return $ Simple_mod tm
else case maybeResult r of
[mkDiag Error "unknown modality" tm]
f2 <- minExpFORMULA minExpForm s f
return $ BoxOrDiamond b nm f2 ps
ana_C_SIG_ITEM :: Ana C_SIG_ITEM C_BASIC_ITEM C_SIG_ITEM C_FORMULA CoCASLSign
ana_C_SIG_ITEM _ mi = case mi of
do mapM_ (\ i -> case item i of
CoDatatype_decl s _ _ -> addSort NonEmptySorts i s) al
mapAnM (ana_CODATATYPE_DECL Loose) al
isCoConsAlt :: COALTERNATIVE -> Bool
isCoConsAlt a = case a of
getCoSubsorts :: COALTERNATIVE -> [SORT]
getCoSubsorts c = case c of
-- | return list of constructors
ana_CODATATYPE_DECL :: GenKind -> CODATATYPE_DECL -> State CSign [Component]
ana_CODATATYPE_DECL gk (CoDatatype_decl s al _) = do
ul <- mapM (ana_COALTERNATIVE s) al
let constr = catMaybes ul
unless (null constr) $ do
addDiags $ checkUniqueness cs
wrongConstr = filter ((totalSels /=) . snd) constr
addDiags $ map (\ (c, _) -> mkDiag Error
("total selectors '" ++ showSepList (showString ",")
"'\n must appear in alternative") c) wrongConstr
let (alts, subs) = partition isCoConsAlt $ map item al
sbs = concatMap getCoSubsorts subs
comps = map (getCoConsType s) alts
ttrips = map ((\ (a, vs, ses) -> (a, vs, catSels ses))
sels = concatMap (\ (_, _, ses) -> ses) ttrips
addSentences $ mapMaybe comakeInjective
$ filter (\ (_, _, ces) -> not $ null ces)
addSentences $ makeDisjSubsorts s sbs
addSentences $ catMaybes $ concatMap
(\ c -> map (comakeDisjToSort c) sbs)
addSentences $ comakeDisjoint comps
let ttrips' = [(a, vs, t, ses) | (Just (a, t), vs, ses) <- ttrips]
addSentences $ catMaybes $ concatMap
map (makeUndefForm ses) ttrips') sels
getCoConsType :: SORT -> COALTERNATIVE -> (Maybe Id, OpType, [COCOMPONENTS])
let (part, i, il) = case c of
CoSubsorts _ _ -> error "getCoConsType"
Co_construct k a l _ -> (k, a, l)
in (i, OpType part (concatMap
(map (opRes . snd) . getCoCompType s) il) s, il)
getCoCompType :: SORT -> COCOMPONENTS -> [(Id, OpType)]
getCoCompType s (CoSelect l (Op_type k args res _) _) =
map (\ i -> (i, OpType k (args ++ [s]) res)) l
coselForms :: (Maybe Id, OpType, [COCOMPONENTS]) -> [Named (FORMULA f)]
coselForms x = case coselForms1 "X" x of
(Just (i, f), vs, cs) -> makeSelForms 1 (i, vs, f, cs)
coselForms1 :: String -> (Maybe Id, OpType, [COCOMPONENTS])
-> (Maybe (Id, TERM f), [VAR_DECL], [(Maybe Id, OpType)])
coselForms1 str (i, ty, il) =
let cs = concatMap (getCoCompType $ opRes ty) il
vs = genSelVars str 1 $ map snd cs
Just i' -> Just (i', Application (Qual_op_name i'
(toOP_TYPE ty) nullRange)
(map toQualVar vs) nullRange)
in (it, vs, map (\ (j, typ) -> (Just j, typ)) cs)
comakeDisjToSort :: (Maybe Id, OpType, [COCOMPONENTS]) -> SORT
-> Maybe (Named (FORMULA f))
comakeDisjToSort a s = do
let (i, v, _) = coselForms1 "X" a
return $ makeNamed ("ga_disjoint_" ++ showId c "_sort_" ++ showId s "")
$ mkForall v (Negation (Membership t s p) p) p
comakeInjective :: (Maybe Id, OpType, [COCOMPONENTS])
-> Maybe (Named (FORMULA f))
let (i1, v1, _) = coselForms1 "X" a
(i2, v2, _) = coselForms1 "Y" a
return $ makeNamed ("ga_injective_" ++ showId c "") $
(Equivalence (Strong_equation t1 t2 p)
(let ces = zipWith (\ w1 w2 -> Strong_equation
(toQualVar w1) (toQualVar w2) p) v1 v2
in if isSingle ces then head ces else Conjunction ces p)
comakeDisjoint :: [(Maybe Id, OpType, [COCOMPONENTS])] -> [Named (FORMULA f)]
comakeDisjoint l = case l of
a : as -> mapMaybe (comakeDisj a) as ++ comakeDisjoint as
comakeDisj :: (Maybe Id, OpType, [COCOMPONENTS])
-> (Maybe Id, OpType, [COCOMPONENTS])
-> Maybe (Named (FORMULA f))
let (i1, v1, _) = coselForms1 "X" a1
(i2, v2, _) = coselForms1 "Y" a2
let p = posOfId c1 `appRange` posOfId c2
return $ makeNamed ("ga_disjoint_" ++ showId c1 "_" ++ showId c2 "")
$ mkForall (v1 ++ v2) (Negation (Strong_equation t1 t2 p) p) p
-- | return the constructor and the set of total selectors
ana_COALTERNATIVE :: SORT -> Annoted COALTERNATIVE
-> State CSign (Maybe (Component,
Set.Set Component))
ana_COALTERNATIVE s c = case item c of
let cons@(i, ty, il) = getCoConsType s ci
ul <- mapM (ana_COCOMPONENTS s) il
let ts = concatMap fst ul
addDiags $ checkUniqueness (ts ++ concatMap snd ul)
addSentences $ coselForms cons
Nothing -> return Nothing
-- | return total and partial selectors
ana_COCOMPONENTS :: SORT -> COCOMPONENTS
-> State CSign ([Component], [Component])
ana_COCOMPONENTS s c = do
let cs = getCoCompType s c
sels <- mapM (\ (i, ty) ->
do addOp (emptyAnno ()) ty i
return $ Just $ Component i ty) cs
return $ partition (isTotal . compType) $ catMaybes sels
:: Ana C_BASIC_ITEM C_BASIC_ITEM C_SIG_ITEM C_FORMULA CoCASLSign
ana_C_BASIC_ITEM mix bi = case bi of
do mapM_ (\ i -> case item i of
CoDatatype_decl s _ _ -> addSort NonEmptySorts i s) al
mapAnM (ana_CODATATYPE_DECL Free) al
toCoSortGenAx ps True $ getCoDataGenSig al
do (gs, ul) <- ana_CoGenerated ana_C_SIG_ITEM mix ([], al)
toCoSortGenAx ps False $ unionGenAx gs
return $ CoSort_gen ul ps
toCoSortGenAx :: Range -> Bool -> GenAx -> State CSign ()
toCoSortGenAx ps isFree (sorts, rel, ops) = do
opSyms = map (\ c -> let ide = compId c in Qual_op_name ide
(toOP_TYPE $ compType c) $ posOfId ide) $
Set.toList ops
injSyms = map (\ (s, t) -> let p = posOfId s in
Qual_op_name (mkUniqueInjName s t)
$ addDiags [Diag Error "missing cogenerated sort" ps]
addSentences [makeNamed ("ga_cogenerated_" ++ showSepList (showString "_")
$ ExtFORMULA $ CoSort_gen_ax sortList
(opSyms ++ injSyms) isFree]
ana_CoGenerated :: Ana C_SIG_ITEM C_BASIC_ITEM C_SIG_ITEM C_FORMULA CoCASLSign
-> Ana ([GenAx], [Annoted (SIG_ITEMS C_SIG_ITEM C_FORMULA)])
C_BASIC_ITEM C_SIG_ITEM C_FORMULA CoCASLSign
ana_CoGenerated anaf mix (_, al) = do
ul <- mapAnM (ana_SIG_ITEMS minExpForm anaf mix Generated) al
return (map (getCoGenSig . item) ul, ul)
getCoGenSig :: SIG_ITEMS C_SIG_ITEM C_FORMULA -> GenAx
getCoGenSig si = case si of
Sort_items _ al _ -> unionGenAx $ map (getGenSorts . item) al
Datatype_items _ dl _ -> getDataGenSig dl
Ext_SIG_ITEMS (CoDatatype_items dl _) -> getCoDataGenSig dl
getCoDataGenSig :: [Annoted CODATATYPE_DECL] -> GenAx
let get_sel (s, a) = case a of
Co_construct _ _ l _ -> concatMap (getCoCompType s) l
alts = concatMap ((\ (CoDatatype_decl s al _) ->
map (\ a -> (s, item a)) al) . item) dl
(realAlts, subs) = partition (isCoConsAlt . snd) alts
sels = map (uncurry Component) $ concatMap get_sel realAlts
rel = foldr (\ (t, a) r -> foldr (`
Rel.insert` t) r $ getCoSubsorts a)