342N/ADescription : static analysis of CASL (heterogeneous) structured specifications
342N/ACopyright : (c) Till Mossakowski and Uni Bremen 2003-2006
342N/AMaintainer : till@informatik.uni-bremen.de
342N/AStatic analysis of CASL (heterogeneous) structured specifications
342N/A Follows the verfication semantic rules in Chap. IV:4.7
342N/A of the CASL Reference Manual.
342N/A-- Parameters: global context, local environment,
342N/A-- the SIMPLE_ID may be a name if the specification shall be named,
342N/A-- options: here we need the info: shall only the structure be analysed?
342N/Aana_SPEC :: LogicGraph -> DGraph -> MaybeNode -> NODE_NAME ->
342N/A HetcatsOpts -> SPEC -> Result (SPEC, NodeSig, DGraph)
342N/Aana_SPEC lg dg nsig name opts sp = case sp of
342N/A Basic_spec (G_basic_spec lid bspec) ->
342N/A do G_sign lid' sigma' i1 <- return (getMaybeSig nsig)
342N/A sigma <- coerceSign lid' lid "Analysis of basic spec" sigma'
342N/A (bspec', sigma_complete, ax) <-
342N/A then return (bspec, empty_signature lid, [])
342N/A else do b <- maybeToMonad
342N/A ("no basic analysis for logic "
342N/A b (bspec, sigma, globalAnnos dg)
342N/A let (sgMap, s) = sigMapI dg
342N/A (mrMap, m) = morMapI dg
342N/A gsig = G_sign lid sigma_complete (s+1)
342N/A incl <- ginclusion lg (G_sign lid sigma i1) gsig
342N/A let gTh = G_theory lid sigma_complete (s+1) (toThSens ax) (t+1)
342N/A DGNode { dgn_name = name
342N/A -- no, not only the delta
342N/A , dgn_cons_status = LeftOpen
342N/A , dgn_lock = error "uninitialized MVar of DGNode"
342N/A dg' = insNodeDG (node,node_contents) dg
342N/A incl' = updateMorIndex (m+1) incl
342N/A link = DGLink { dgl_morphism = incl'
342N/A , dgl_origin = DGExtension
342N/A , dgl_id = defaultEdgeID
342N/A JustNode (NodeSig n _) -> insLEdgeNubDG (n,node,link) dg'
342N/A return (Basic_spec (G_basic_spec lid bspec'),
342N/A (sp1', NodeSig n' gsigma, dg') <-
342N/A ana_SPEC lg dg nsig (inc name) opts sp1
342N/A let (mrMap, m) = morMapI dg'
342N/A mor <- ana_RENAMING lg nsig gsigma opts ren
342N/A -- ??? check that mor is identity on local env
342N/A let gsigma' = cod Grothendieck mor
342N/A -- ??? too simplistic for non-comorphism inter-logic translations
342N/A G_sign lid' gsig ind <- return gsigma'
342N/A let node_contents = DGNode
342N/A , dgn_theory = G_theory lid' gsig ind noSens 0
342N/A , dgn_origin = DGTranslation
342N/A , dgn_cons_status = LeftOpen
342N/A , dgn_lock = error "uninitialized MVar of DGNode"
342N/A node = getNewNodeDG dg'
342N/A mor' = updateMorIndex (m+1) mor
342N/A , dgl_origin = DGTranslation
342N/A , dgl_id = defaultEdgeID
342N/A dg'' = insNodeDG (node,node_contents) dg'
342N/A return (Translation (replaceAnnoted sp1' asp) ren,
342N/A (insLEdgeNubDG link dg''))
342N/A (sp1', NodeSig n' gsigma', dg') <-
342N/A ana_SPEC lg dg nsig (inc name) opts sp1
342N/A let gsigma = getMaybeSig nsig
342N/A (mrMap, m) = morMapI dg'
342N/A (hmor,tmor) <- ana_RESTRICTION dg gsigma gsigma' opts restr
342N/A -- we treat hiding and revealing differently
342N/A -- in order to keep the dg as simple as possible
342N/A let hmor' = updateMorIndex (m+1) hmor
342N/A do let gsigma'' = dom Grothendieck hmor
342N/A -- ??? too simplistic for non-comorphism inter-logic reductions
342N/A G_sign lid' gsig ind <- return gsigma''
342N/A let node_contents = DGNode
342N/A , dgn_theory = G_theory lid' gsig ind noSens 0
342N/A , dgn_origin = DGHiding
342N/A , dgn_cons_status = LeftOpen
342N/A , dgn_lock = error "uninitialized MVar of DGNode"
342N/A node = getNewNodeDG dg'
342N/A , dgl_origin = DGHiding
342N/A , dgl_id = defaultEdgeID
342N/A dg'' = insNodeDG (node,node_contents) dg'
342N/A return (Reduction (replaceAnnoted sp1' asp) restr,
342N/A (insLEdgeNubDG link dg''))
let gsigma1 = dom Grothendieck tmor'
gsigma'' = cod Grothendieck tmor'
-- ??? too simplistic for non-comorphism inter-logic reductions
G_sign lid1 gsig ind <- return gsigma1
G_sign lid'' gsig'' ind'' <- return gsigma''
-- the case with identity translation leads to a simpler dg
if tmor' == ide Grothendieck (dom Grothendieck tmor')
let node1 = getNewNodeDG dg'
, dgn_theory = G_theory lid1 gsig ind noSens 0
, dgn_origin = DGRevealing
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
, dgl_origin = DGRevealing
dg'' = insNodeDG (node1,node_contents1) dg'
return (Reduction (replaceAnnoted sp1' asp) restr,
setMorMapDG (
Map.insert (m+1) (toG_morphism hmor')
(insLEdgeNubDG link1 dg''))
let [node1,node''] = newNodesDG 2 dg'
{ dgn_name = extName "T" name
, dgn_theory = G_theory lid1 gsig ind noSens 0
, dgn_origin = DGRevealing
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
, dgl_origin = DGRevealing
, dgn_theory = G_theory lid'' gsig'' ind'' noSens 0
, dgn_origin = DGRevealTranslation
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
link'' = (node1,node'',DGLink
, dgl_origin = DGRevealTranslation
return (Reduction (replaceAnnoted sp1' asp) restr,
setMorMapDG (
Map.insert (m+1) (toG_morphism hmor')
insNodeDG (node'',node_contents'') $
insNodeDG (node1,node_contents1) dg'))
Union [] pos -> adjustPos pos $ fail $ "empty union"
do let sps = map item asps
(sp1,nsig',dg1) <- ana_SPEC lg dg' nsig n opts sp'
return (sp1:sps1,nsig':nsigs,dg1,inc n)
in foldl ana (return ([], [], dg, extName "U" name)) sps
let nsigs' = reverse nsigs
gbigSigma <- adj $ gsigManyUnion lg (map getSig nsigs')
G_sign lid' gsig _ <- return gbigSigma
gbigSigma' <- return $ G_sign lid' gsig (s+1)
let node_contents = DGNode
, dgn_theory = G_theory lid' gsig (s+1) noSens 0
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
dg1 = insNodeDG (node, node_contents) dg'
dg2 = setSigMapDG (
Map.insert (s+1) gbigSigma' sgMap) dg1
insE mdg (NodeSig n gsigma) = do
let (mrMapl, ml) = morMapI dgl
incl <- adj $ ginclusion lg gsigma gbigSigma
let incl' = updateMorIndex (ml+1) incl
(toG_morphism incl') mrMapl)
(insLEdgeNubDG (n,node,link) dgl)
dg3 <- foldl insE (return dg2) nsigs'
return (Union (map (uncurry replaceAnnoted)
(zip (reverse sps') asps))
NodeSig node gbigSigma', dg3)
(sps',nsig1',dg1, _, _, _) <-
foldl ana_Extension (return ([], nsig, dg, lg, opts, pos)) namedSps
EmptyNode _ -> fail "empty extension"
JustNode nsig1 -> return (Extension (map (uncurry replaceAnnoted)
(zip (reverse sps') asps))
namedSps = zip (reverse (name: tail (take (length asps)
(iterate inc (extName "E" name)))))
(sp', NodeSig n' gsigma'@(G_sign lid' gsig ind), dg') <-
ana_SPEC lg dg nsig (inc name) opts sp1
incl <- adjustPos pos $ ginclusion lg (getMaybeSig nsig) gsigma'
let incl' = updateMorIndex (m+1) incl
, dgn_theory = G_theory lid' gsig ind noSens 0 -- delta is empty
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
, dgl_type = FreeDef nsig
return (Free_spec (replaceAnnoted sp' asp) poss,
setMorMapDG (
Map.insert (m+1) (toG_morphism incl') mrMap)
(insLEdgeNubDG link $ insNodeDG (node,node_contents) dg'))
(sp', NodeSig n' gsigma'@(G_sign lid' gsig ind), dg') <-
ana_SPEC lg dg nsig (inc name) opts sp1
incl <- adjustPos pos $ ginclusion lg (getMaybeSig nsig) gsigma'
let incl' = updateMorIndex (m+1) incl
, dgn_theory = G_theory lid' gsig ind noSens 0 -- delta is empty
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
, dgl_type = CofreeDef nsig
return (Cofree_spec (replaceAnnoted sp' asp) poss,
setMorMapDG (
Map.insert (m+1) (toG_morphism incl') mrMap)
(insLEdgeNubDG link $ insNodeDG (node,node_contents) dg'))
Local_spec asp asp' poss ->
(sp2, nsig'@(NodeSig _ (G_sign lid' sigma' _)), dg') <-
ana_SPEC lg dg nsig (extName "L" name) opts sp1
(sp2', NodeSig n'' (G_sign lid'' sigma'' _), dg'') <-
ana_SPEC lg dg' (JustNode nsig') (inc name) opts sp1'
let gsigma = getMaybeSig nsig
(sgMap, s) = sigMapI dg''
(mrMap, m) = morMapI dg''
G_sign lid sigma _ <- return gsigma
sigma1 <- coerceSign lid' lid "Analysis of local spec" sigma'
sigma2 <- coerceSign lid'' lid "Analysis of local spec" sigma''
let sys = sym_of lid sigma
mor3 <- if isStructured opts then return (ide lid sigma2)
else adjustPos pos $ cogenerated_sign lid
let sigma3 = dom lid mor3
-- gsigma2 = G_sign lid sigma2
gsigma3 = G_sign lid sigma3 (s+1)
when (not( isStructured opts ||
"illegal use of locally declared symbols: "
let node_contents = DGNode
, dgn_theory = G_theory lid sigma3 (s+1) noSens 0
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
link = (n'', node, DGLink
{ dgl_morphism = gEmbed2 gsigma3 (G_morphism lid 0 mor3 (m+1) 0)
return (Local_spec (replaceAnnoted sp2 asp)
(replaceAnnoted sp2' asp')
setMorMapDG (
Map.insert (m+1) (G_morphism lid 0 mor3 (m+1) 0)
(insLEdgeNubDG link $ insNodeDG (node,node_contents) dg''))
-- analyse spec with empty local env
(sp', NodeSig n' gsigma', dg') <-
ana_SPEC lg dg (EmptyNode l) (inc name) opts sp1
let gsigma = getMaybeSig nsig
gsigma'' <- adj $ gsigUnion lg gsigma gsigma'
G_sign lid'' gsig'' _ <- return gsigma''
gsigma2 <- return $ G_sign lid'' gsig'' (s+1)
incl1 <- adj $ ginclusion lg gsigma gsigma2
incl2 <- adj $ ginclusion lg gsigma' gsigma2
let incl1' = updateMorIndex (m+1) incl1
incl2' = updateMorIndex (m+2) incl2
, dgn_theory = G_theory lid'' gsig'' (s+1) noSens 0
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
, dgl_origin = DGClosedLenv
JustNode (NodeSig n _) -> insLEdgeNubDG (n, node, link1)
morMap1 =
Map.insert (m+1) (toG_morphism incl1') mrMap
morMap2 =
Map.insert (m+2) (toG_morphism incl2') morMap1
return (Closed_spec (replaceAnnoted sp' asp) pos,
(insLink1 $ insLEdgeNubDG link2
$ insNodeDG (node,node_contents) dg'))
Qualified_spec (Logic_name ln sublog) asp pos -> do
l <- lookupLogic "Static analysis: " (tokStr ln) lg
-- analyse spec with empty local env
(sp', NodeSig n' gsigma', dg') <-
ana_SPEC lg dg (EmptyNode l) (inc name) opts (item asp)
-- construct union with local env
let gsigma = getMaybeSig nsig
gsigma'' <- adj $ gsigUnion lg gsigma gsigma'
G_sign lid'' gsig'' _ <- return gsigma''
gsigma2 <- return $ G_sign lid'' gsig'' (s+1)
incl1 <- adj $ ginclusion lg gsigma gsigma2
incl2 <- adj $ ginclusion lg gsigma' gsigma2
let incl1' = updateMorIndex (m+1) incl1
incl2' = updateMorIndex (m+2) incl2
, dgn_theory = G_theory lid'' gsig'' (s+1) noSens 0
, dgn_origin = DGLogicQual
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
, dgl_origin = DGLogicQualLenv
, dgl_origin = DGLogicQual
JustNode (NodeSig n _) -> insLEdgeNubDG (n, node, link1)
morMap1 =
Map.insert (m+1) (toG_morphism incl1') mrMap
morMap2 =
Map.insert (m+2) (toG_morphism incl2') morMap1
return (Qualified_spec (Logic_name ln sublog)
(replaceAnnoted sp' asp) pos,
( insLink1 $ insLEdgeNubDG link2 $
insNodeDG (node,node_contents) dg'))
(sp',nsig',dg') <- ana_SPEC lg dg nsig name opts (item asp)
return (Group (replaceAnnoted sp' asp) pos,nsig',dg')
Spec_inst spname afitargs pos0 -> do
let pos = if null afitargs then tokPos spname else pos0
case lookupGlobalEnvDG spname dg of
("Specification " ++ spstr ++ " not found") pos
(spstr ++ " is a view, not a specification") pos
" is an architectural, not a structured specification") pos
" is a unit specification, not a structured specification") pos
" is a refinement specification, not a structured specification") pos
Just (SpecEntry gs@(imps,params,_,body@(NodeSig nB gsigmaB))) ->
case (\x y -> (x,x-y)) (length afitargs) (length params) of
-- the case without parameters leads to a simpler dg
adj $ gsigUnion lg (getMaybeSig nsig) gsigmaB
let gsigma' = G_sign lid gsig (s+1)
-- the subcase with empty local env leads to an even simpler dg
-- if the node shall not be named and the logic does not change,
if isInternal name && langNameSig gsigma'==langNameSig gsigmaB
-- then just return the body
then return (sp, body, dg)
-- otherwise, we need to create a new one
incl <- adj $ ginclusion lg gsigmaB gsigma'
let incl' = updateMorIndex (m+1) incl
, dgn_theory = G_theory lid gsig (s+1) noSens 0
, dgn_origin = DGSpecInst spname
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
, dgl_origin = DGSpecInst spname
setMorMapDG (
Map.insert (m+1) (toG_morphism incl')
(insLEdgeNubDG link $ insNodeDG (node,node_contents) dg))
-- the subcase with nonempty local env
JustNode (NodeSig n sigma) -> do
incl1 <- adj $ ginclusion lg sigma gsigma'
incl2 <- adj $ ginclusion lg gsigmaB gsigma'
let incl1' = updateMorIndex (m+1) incl1
incl2' = updateMorIndex (m+2) incl2
, dgn_theory = G_theory lid gsig (s+1) noSens 0
, dgn_origin = DGSpecInst spname
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
, dgl_origin = DGSpecInst spname
, dgl_origin = DGSpecInst spname
morMap1 =
Map.insert (m+1) (toG_morphism incl1') mrMap
morMap2 =
Map.insert (m+2) (toG_morphism incl2') morMap1
insNodeDG (node,node_contents) dg))
-- now the case with parameters
let fitargs = map item afitargs
(fitargs', dg', args, _) <-
adj $ foldl anaFitArg (return ([], dg, [], extName "A" name))
let actualargs = reverse args
(gsigma',morDelta) <- adj $ apply_GS lg gs actualargs
gsigmaRes <- adj $ gsigUnion lg (getMaybeSig nsig) gsigma'
G_sign lidRes gsigRes _ <- return gsigmaRes
gsigmaRes' <- return $ G_sign lidRes gsigRes (s+1)
incl1 <- adj $ ginclusion lg (getMaybeSig nsig) gsigmaRes'
incl2 <- adj $ ginclusion lg gsigma' gsigmaRes'
let incl1' = updateMorIndex (m+1) incl1
incl2' = updateMorIndex (m+2) incl2
morDelta' <- comp Grothendieck (gEmbed morDelta) incl2'
let node = getNewNodeDG dg'
, dgn_theory = G_theory lidRes gsigRes (s+1) noSens 0
, dgn_origin = DGSpecInst spname
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
, dgl_origin = DGSpecInst spname
JustNode (NodeSig n _) -> insLEdgeNubDG (n, node, link1)
{ dgl_morphism = morDelta'
, dgl_origin = DGSpecInst spname
parLinks = catMaybes (map (parLink gsigmaRes' node) actualargs)
morMap1 =
Map.insert (m+1) (toG_morphism incl1') mrMap
morMap2 =
Map.insert (m+2) (toG_morphism incl2') morMap1
(map (uncurry replaceAnnoted)
(zip (reverse fitargs') afitargs))
(insLink1 $ insLEdgeNubDG link2 $
insNodeDG (node,node_contents) dg')
anaFitArg res (nsig', fa) = do
(fas', dg1, args, name') <- res
(fa', dg', arg) <- ana_FIT_ARG lg dg1 spname imps nsig' opts name' fa
return (fa' : fas', dg', arg : args , inc name')
parLink gsigma' node (_mor_i, NodeSig nA_i sigA_i) = do
incl <- maybeResult $ ginclusion lg sigA_i gsigma'
-- finally the case with conflicting numbers of formal and actual parameters
(spstr ++ " expects " ++ show (length params) ++ " arguments"
++ " but was given " ++ show (length afitargs)) pos
Data (Logic lidD) (Logic lidP) asp1 asp2 pos ->
Comorphism cid <- adj $ logicInclusion lg (Logic lidD) (Logic lidP)
let lidD' = sourceLogic cid
(sp1', NodeSig n' (G_sign lid' sigma' _), dg1) <-
ana_SPEC lg dg (EmptyNode (Logic lidD)) (inc name) opts sp1
sigmaD <- adj $ coerceSign lid' lidD' "Analysis of data spec" sigma'
(sigmaD',sensD') <- adj $ map_sign cid sigmaD
let gsigmaD' = G_sign lidP' sigmaD' 0
, dgn_theory = G_theory lidP' sigmaD' 0 (toThSens sensD') 0
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
{ dgl_morphism = GMorphism cid sigmaD 0 (ide lidP' sigmaD') 0
dg2 = insLEdgeNubDG link $
insNodeDG (node,node_contents) dg1
nsig2 = NodeSig node gsigmaD'
(sp2',nsig3,dg3) <- ana_SPEC lg dg2 (JustNode nsig2) name opts sp2
return (Data (Logic lidD) (Logic lidP)
(replaceAnnoted sp1' asp1)
(replaceAnnoted sp2' asp2)
ana_ren1 :: LogicGraph -> MaybeNode -> Range -> GMorphism -> G_mapping
ana_ren1 _ lenv _pos (GMorphism r sigma ind1 mor _)
(G_symb_map (G_symb_map_items_list lid sis)) = do
sis1 <- coerceSymbMapItemsList lid lid2 "Analysis of renaming" sis
rmap <- stat_symb_map_items lid2 sis1
mor1 <- induced_from_morphism lid2 rmap (cod lid2 mor)
JustNode (NodeSig _ (G_sign lidLenv sigmaLenv _)) -> do
-- needs to be changed for logic translations
sigmaLenv' <- coerceSign lidLenv lid2
"Analysis of renaming: logic translations not yet properly handeled"
let sysLenv = sym_of lid2 sigmaLenv'
{- when (not (forbiddenSys ==
Set.empty)) $ plain_error () (
"attempt to rename the following symbols from the local environment:\n"
++ showDoc forbiddenSys "") pos
mor2 <- comp lid2 mor mor1
return $ GMorphism r sigma ind1 mor2 0
ana_ren1 lg _ _ mor (G_logic_translation (Logic_code tok src tar pos1)) = do
G_sign srcLid srcSig ind<- return (cod Grothendieck mor)
Comorphism cid <- lookupComorphism (tokStr ctok) lg
when (isJust src && getLogicStr (fromJust src) /=
language_name (sourceLogic cid))
(fail (getLogicStr (fromJust src) ++
"is not the source logic of "
when (isJust tar && getLogicStr (fromJust tar) /=
language_name (targetLogic cid))
(fail (getLogicStr (fromJust tar) ++
"is not the target logic of "
Just (Logic_name l _) -> do
tarL <- lookupLogic "with logic: " (tokStr l) lg
logicInclusion lg (Logic srcLid) tarL
Nothing -> fail "with logic: cannot determine comorphism"
mor1 <- adj $ gEmbedComorphism c (G_sign srcLid srcSig ind)
adj $ comp Grothendieck mor mor1
where getLogicStr (Logic_name l _) = tokStr l
ana_ren :: LogicGraph -> MaybeNode -> Range -> Result GMorphism -> G_mapping
ana_ren lg lenv pos mor_res ren =
ana_ren1 lg lenv pos mor ren
ana_RENAMING :: LogicGraph -> MaybeNode -> G_sign -> HetcatsOpts -> RENAMING
ana_RENAMING lg lenv gSigma opts (Renaming ren pos) =
then return (ide Grothendieck gSigma)
else foldl (ana_ren lg lenv pos) (return (ide Grothendieck gSigma)) ren
-- analysis of restrictions
ana_restr1 :: DGraph -> G_sign -> Range -> GMorphism -> G_hiding
ana_restr1 _ (G_sign lidLenv sigmaLenv _) pos
(GMorphism cid sigma1 _ mor _)
(G_symb_list (G_symb_items_list lid' sis')) = do
let lid1 = sourceLogic cid
sis1 <- coerceSymbItemsList lid' lid1 "Analysis of restriction" sis'
rsys <- stat_symb_items lid1 sis1
let sys = sym_of lid1 sigma1
sys' =
Set.filter (\ sy -> any (matches lid1 sy) rsys) sys
( \ sy -> matches lid1 sy rsy) sys') rsys
when (not $ null unmatched)
$ plain_error () ("attempt to hide unknown symbols:\n"
++ showDoc unmatched "") pos
-- needs to be changed when logic projections are implemented
sigmaLenv' <- coerceSign lidLenv lid1
"Analysis of restriction: logic projections not yet properly handeled"
let sysLenv = sym_of lid1 sigmaLenv'
"attempt to hide the following symbols from the local environment:\n"
++ showDoc forbiddenSys "") pos
mor1 <- cogenerated_sign lid1 sys' sigma1
mor1' <- map_morphism cid mor1
mor2 <- comp lid2 mor1' mor
return $ GMorphism cid (dom lid1 mor1) 0 mor2 0
ana_restr1 _dg _gSigma _mor _pos
(G_logic_projection (Logic_code _tok _src _tar pos1)) =
fatal_error "no analysis of logic projections yet" pos1
ana_restr :: DGraph -> G_sign -> Range -> Result GMorphism -> G_hiding
ana_restr dg gSigma pos mor_res restr =
ana_restr1 dg gSigma pos mor restr
ana_RESTRICTION :: DGraph -> G_sign -> G_sign -> HetcatsOpts -> RESTRICTION
-> Result (GMorphism, Maybe GMorphism)
ana_RESTRICTION dg gSigma gSigma' opts restr =
ana_RESTRICTION' dg gSigma gSigma' (isStructured opts) restr
ana_RESTRICTION' :: DGraph -> G_sign -> G_sign -> Bool -> RESTRICTION
-> Result (GMorphism, Maybe GMorphism)
ana_RESTRICTION' _ _ gSigma True _ =
return (ide Grothendieck gSigma,Nothing)
ana_RESTRICTION' dg gSigma gSigma' False (Hidden restr pos) =
do mor <- foldl (ana_restr dg gSigma pos)
(return (ide Grothendieck gSigma'))
-- ??? Need to check that local env is not affected !
ana_RESTRICTION' _ (G_sign lid sigma _) (G_sign lid' sigma' si')
False (Revealed (G_symb_map_items_list lid1 sis) pos) =
do let sys = sym_of lid sigma -- local env
sys' = sym_of lid' sigma' -- "big" signature
sis' <- adj $ coerceSymbMapItemsList lid1 lid'
"Analysis of restriction" sis
rmap <- adj $ stat_symb_map_items lid' sis'
-- domain of rmap intersected with sys'
-- domain of rmap should be checked to match symbols from sys' ???
sys1 <- adj $ coerceSymbolSet lid lid' "Analysis of restriction" sys
-- ??? this is too simple in case that local env is translated
mor1 <- adj $ generated_sign lid' (sys1 `
Set.union` sys'') sigma'
mor2 <- adj $ induced_from_morphism lid' rmap (dom lid' mor1)
return (gEmbed (G_morphism lid' si' mor1 0 0),
Just (gEmbed (G_morphism lid' 0 mor2 0 0)))
ana_FIT_ARG :: LogicGraph -> DGraph -> SPEC_NAME -> MaybeNode
-> NodeSig -> HetcatsOpts -> NODE_NAME -> FIT_ARG
-> Result (FIT_ARG, DGraph, (G_morphism,NodeSig))
ana_FIT_ARG lg dg spname nsigI
(NodeSig nP (G_sign lidP sigmaP _)) opts name
(Fit_spec asp gsis pos) = do
(sp', nsigA@(NodeSig nA (G_sign lidA sigmaA _)), dg') <-
ana_SPEC lg dg nsigI name opts (item asp)
G_symb_map_items_list lid sis <- homogenizeGM (Logic lidP) gsis
sigmaA' <- adj $ coerceSign lidA lidP "Analysis of fitting argument" sigmaA
mor <- adj $ if isStructured opts then return (ide lidP sigmaP)
rmap <- stat_symb_map_items lid sis
else coerceRawSymbolMap lid lidP
"Analysis of fitting argument" rmap
(\ s -> matches lidP s r) $ sym_of lidP sig
unknowns = filter (noMatch sigmaP) (
Map.keys rmap')
++ filter (noMatch sigmaA') (
Map.elems rmap')
induced_from_to_morphism lidP rmap' sigmaP sigmaA'
else fatal_error ("unknown symbols " ++ showDoc unknowns "") pos
let symI = sym_of lidP sigmaI'
symmap_mor = symmap_of lidP mor
-- are symbols of the imports left untouched?
if
Set.all (\sy -> lookupFM symmap_mor sy == Just sy) symI
else plain_error () "Fitting morphism must not affect import" pos
-- ??? also output some symbol that is affected
{ dgl_morphism = gEmbed (G_morphism lidP 0 mor 0 0)
, dgl_type = GlobalThm LeftOpen None LeftOpen
, dgl_origin = DGSpecInst spname
return (Fit_spec (replaceAnnoted sp' asp) gsis pos,
(G_morphism lidP 0 mor 0 0,nsigA)
ana_FIT_ARG lg dg spname nsigI (NodeSig nP gsigmaP)
opts name fv@(Fit_view vn afitargs pos) = do
case lookupGlobalEnvDG vn dg of
("View " ++ tokStr vn ++ " not found") pos
(spstr ++ " is a specification, not a view") pos
" is an architectural specification, not a view ") pos
" is a unit specification, not a view") pos
" is a refinement specification, not a view") pos
Just (ViewEntry (src,mor,gs@(imps,params,_,target))) -> do
gsigmaI = getMaybeSig nsigI
GMorphism cid _ _ morHom ind<- return mor
let lid = targetLogic cid
when (not (language_name (sourceLogic cid) == language_name lid))
"heterogeneous fitting views not yet implemented"
case (\x y -> (x,x-y)) (length afitargs) (length params) of
-- the case without parameters leads to a simpler dg
-- the subcase with empty import leads to a simpler dg
let link = (nP,nSrc,DGLink
{ dgl_morphism = ide Grothendieck gsigmaP
, dgl_type = GlobalThm LeftOpen None LeftOpen
, dgl_origin = DGFitView spname
return (fv, insLEdgeNubDG link dg,
(G_morphism lid 0 morHom ind 0, target))
-- the subcase with nonempty import
JustNode (NodeSig nI _) -> do
gsigmaIS <- adj $ gsigUnion lg gsigmaI gsigmaS
when (not (isSubGsign lg gsigmaP gsigmaIS))
("Parameter does not match source of fittig view. "
++ "Parameter signature:\n"
"\nSource signature of fitting view (united with import):\n"
++ showDoc gsigmaIS "") pos)
G_sign lidI sigI1 _<- return gsigmaI
sigI <- adj $ coerceSign lidI lid
"Analysis of instantiation with import" sigI1
mor_I <- adj $ morphism_union lid morHom $ ide lid sigI
gsigmaA <- adj $ gsigUnion lg gsigmaI gsigmaT
G_sign lidA gsigA indA <- return gsigmaA
G_sign lidP gsigP indP <- return gsigmaP
incl1 <- adj $ ginclusion lg gsigmaI gsigmaA
incl2 <- adj $ ginclusion lg gsigmaT gsigmaA
incl3 <- adj $ ginclusion lg gsigmaI gsigmaP
incl4 <- adj $ ginclusion lg gsigmaS gsigmaP
let [nA,n'] = newNodesDG 2 dg
, dgn_theory = G_theory lidA gsigA indA noSens 0
, dgn_origin = DGFitViewA spname
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
, dgn_theory = G_theory lidP gsigP indP noSens 0
, dgn_origin = DGFitView spname
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
{ dgl_morphism = ide Grothendieck gsigmaP
, dgl_type = GlobalThm LeftOpen None LeftOpen
, dgl_origin = DGFitView spname
, dgl_origin = DGFitView spname
, dgl_origin = DGFitViewA spname
, dgl_origin = DGFitViewImp spname
, dgl_origin = DGFitViewAImp spname
return (fv, insLEdgeNubDG link $
insNodeDG (nA,node_contentsA) $
insNodeDG (n',node_contents') dg,
(G_morphism lid 0 mor_I 0 0, NodeSig nA gsigmaA))
-- now the case with parameters
let fitargs = map item afitargs
(fitargs', dg', args,_) <-
foldl anaFitArg (return ([], dg, [], extName "A" name))
let actualargs = reverse args
(gsigmaA,mor_f) <- adj $ apply_GS lg gs actualargs
let gmor_f = gEmbed mor_f
gsigmaRes <- adj $ gsigUnion lg gsigmaI gsigmaA
G_sign lidRes gsigRes indRes<- return gsigmaRes
mor1 <- adj $ comp Grothendieck mor gmor_f
incl1 <- adj $ ginclusion lg gsigmaA gsigmaRes
mor' <- adj $ comp Grothendieck gmor_f incl1
GMorphism cid1 _ _ mor1Hom _<- return mor1
let lid1 = targetLogic cid1
when (not (language_name (sourceLogic cid1) == language_name lid1))
("heterogeneous fitting views not yet implemented")
G_sign lidI sigI1 _<- return gsigmaI
sigI <- adj $ coerceSign lidI lid1
"Analysis of instantiation with parameters" sigI1
theta <- adj $ morphism_union lid1 mor1Hom (ide lid1 sigI)
incl2 <- adj $ ginclusion lg gsigmaI gsigmaRes
incl3 <- adj $ ginclusion lg gsigmaI gsigmaP
incl4 <- adj $ ginclusion lg gsigmaS gsigmaP
G_sign lidP gsigP indP <- return gsigmaP
let [nA,n'] = newNodesDG 2 dg'
, dgn_theory = G_theory lidRes gsigRes indRes noSens 0
, dgn_origin = DGFitViewA spname
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
{ dgn_name = extName "V" name
, dgn_theory = G_theory lidP gsigP indP noSens 0
, dgn_origin = DGFitView spname
, dgn_cons_status = LeftOpen
, dgn_lock = error "uninitialized MVar of DGNode"
{ dgl_morphism = ide Grothendieck gsigmaP
, dgl_type = GlobalThm LeftOpen None LeftOpen
, dgl_origin = DGFitView spname
, dgl_origin = DGFitView spname
, dgl_origin = DGFitViewA spname
fitLinks = [link,link1,link2] ++ case nsigI of
JustNode (NodeSig nI _) -> let
, dgl_origin = DGFitViewImp spname
, dgl_origin = DGFitViewAImp spname
parLinks = catMaybes (map (parLink gsigmaRes nA) actualargs)
(map (uncurry replaceAnnoted)
(zip (reverse fitargs') afitargs))
(insNodeDG (nA,node_contentsA) $
insNodeDG (n',node_contents') dg')
(G_morphism lid1 0 theta 0 0, NodeSig nA gsigmaRes))
anaFitArg res (nsig',fa) = do
(fas',dg1,args,name') <- res
(fa',dg',arg) <- ana_FIT_ARG lg dg1
spname imps nsig' opts name' fa
return (fa':fas',dg',arg:args,inc name')
parLink gsigmaRes node (_mor_i,nsigA_i) = do
let nA_i = getNode nsigA_i
incl <- maybeResult $ ginclusion lg (getSig nsigA_i) gsigmaRes
, dgl_origin = DGFitView spname
-- finally the case with conflicting numbers of formal and actual parameters
(spstr ++ " expects " ++ show (length params) ++ " arguments"
++ " but was given " ++ show (length afitargs)) pos
-- Extension of signature morphisms (for instantitations)
-- first some auxiliary functions
mapID idmap i@(Id toks comps pos1) =
compsnew <- sequence $ map (mapID idmap) comps
return (Id toks compsnew pos1)
Just ids -> if
Set.null ids then return i else
("Identifier component " ++ showId i
" can be mapped in various ways:\n"
++ showDoc ids "") $ getRange i
-> Result (EndoMap Id) -> Result (EndoMap Id)
extID1 idmap i@(Id toks comps pos1) m = do
compsnew <- sequence $ map (mapID idmap) comps
else return (
Map.insert i (Id toks compsnew pos1) m1)
extendMorphism :: G_sign -- ^ formal parameter
-> G_sign -- ^ actual parameter
-> G_morphism -- ^ fitting morphism
-> Result(G_sign,G_morphism)
extendMorphism (G_sign lid sigmaP _) (G_sign lidB sigmaB1 _)
(G_sign lidA sigmaA1 _) (G_morphism lidM _ fittingMor1 _ _) = do
-- for now, only homogeneous instantiations....
sigmaB <- coerceSign lidB lid "Extension of symbol map" sigmaB1
sigmaA <- coerceSign lidA lid "Extension of symbol map" sigmaA1
fittingMor <- coerceMorphism lidM lid "Extension of symbol map" fittingMor1
let symsP = sym_of lid sigmaP
symsB = sym_of lid sigmaB
idsB =
Set.map (sym_name lid) symsB
h = symmap_of lid fittingMor
rh = symbMapToRawSymbMap h
(\sy1 sy2 ->
Rel.setInsert (sym_name lid sy1) (sym_name lid sy2))
(id_to_raw lid id1) (id_to_raw lid id2))
-- do we need combining function catching the clashes???
mor <- induced_from_morphism lid r sigmaB
let hmor = symmap_of lid mor
sigma <- final_union lid sigmaA sigmaAD
(plain_error () ("Symbols shared between actual parameter and body"
++ "\nmust be in formal parameter:\n"
++ showDoc illShared "") nullRange)
comb2 p qs [] ++ comb1 qs
comb2 p@(a, b) ((c, d) : qs) rs =
comb2 p qs $ if b == d then (a, c) : rs else rs
newIdentifications = myKernel hmor Set.\\ myKernel h
when (not (
Set.null newIdentifications))
"Fitting morphism leads to forbidden identifications:\n"
++ showDoc newIdentifications "") nullRange)
incl <- inclusion lid sigmaAD sigma
mor1 <- comp lid mor incl
return (G_sign lid sigma 0, G_morphism lid 0 mor1 0 0)
apply_GS :: LogicGraph -> ExtGenSig -> [(G_morphism,NodeSig)]
-> Result(G_sign,G_morphism)
apply_GS lg (nsigI,_params,gsigmaP,nsigB) args = do
gsigmaA_i = map (getSig . snd) args
gsigmaI = getMaybeSig nsigI
G_sign lidI sigmaI _<- return gsigmaI
let idI = ide lidI sigmaI
gsigmaA <- gsigManyUnion lg gsigmaA_i
mor_f <- homogeneousMorManyUnion (G_morphism lidI 0 idI 0 0:mor_i)
extendMorphism gsigmaP gsigmaB gsigmaA mor_f
-- The first three arguments give the global context
-- The AnyLogic is the current logic
-- The NodeSig is the signature of the parameter of the view
-- flag, whether just the structure shall be analysed
ana_VIEW_TYPE :: LogicGraph -> DGraph -> AnyLogic
-> MaybeNode -> HetcatsOpts -> NODE_NAME -> VIEW_TYPE
-> Result (VIEW_TYPE, (NodeSig, NodeSig), DGraph)
ana_VIEW_TYPE lg dg l parSig opts name
(View_type aspSrc aspTar pos) = do
(spSrc',srcNsig,dg') <- adjustPos pos $
ana_SPEC lg dg (EmptyNode l) (extName "S" name) opts (item aspSrc)
(spTar',tarNsig,dg'') <- adjustPos pos $
(extName "T" name) opts (item aspTar)
return (View_type (replaceAnnoted spSrc' aspSrc)
(replaceAnnoted spTar' aspTar)
(srcNsig, tarNsig), dg'')
-> Result G_symb_map_items_list
homogenizeGM (Logic lid) gsis =
foldl homogenize1 (return (G_symb_map_items_list lid [])) gsis
(G_symb_map_items_list lid2 sis) <- res
sis1' <- coerceSymbMapItemsList lid1 lid2 "" sis1
return $ G_symb_map_items_list lid2 $ sis ++ sis1'
-- | check if structured analysis should be performed
isStructured :: HetcatsOpts -> Bool
isStructured a = case analysis a of
-- | Auxiliary function for not yet implemented features
ana_err f = error $ "*** Analysis of " ++ f ++ " is not yet implemented!"
ana_Extension :: Result ([SPEC],MaybeNode, DGraph,
LogicGraph, HetcatsOpts, Range)
-> (NODE_NAME, Annoted SPEC) ->
Result ([SPEC], MaybeNode, DGraph,
LogicGraph, HetcatsOpts, Range)
ana_Extension res (name',asp') = do
(sps', nsig', dg',lg,opts, pos) <- res
(sp1', nsig1@(NodeSig n1 sig1), dg1) <-
ana_SPEC lg dg' nsig' name' opts (item asp')
let anno = find isSemanticAnno $ l_annos asp'
-- is the extension going between real nodes?
dg2 <- case (anno, nsig') of
(Just anno0@(Semantic_anno anno1 _), JustNode (NodeSig n' sig')) -> do
-- any other semantic annotation? that's an error
when (any (\an -> isSemanticAnno an && an/=anno0) $ l_annos asp')
(plain_error () "Conflicting semantic annotations"
-- %implied should not occur here
"Annotation %implied should come after a BASIC-ITEM"
if anno1==SA_implies then do
when (not (isHomSubGsign sig1 sig')) (plain_error ()
"Signature must not be extended in presence of %implies"
-- insert a theorem link according to p. 319 of the CASL Reference Manual
return $ insLEdgeNubDG (n1, n', DGLink
{ dgl_morphism = ide Grothendieck sig1
, dgl_type = GlobalThm LeftOpen None LeftOpen
, dgl_origin = DGExtension
let anno2 = case anno1 of
-- insert a theorem link according to p. 319 of the CASL Reference Manual
-- the theorem link is trivally proved by the parallel definition link,
-- but for clarity, we leave it open here
-- the interesting open proof obligation is anno2, of course
incl <- ginclusion lg sig' sig1
let incl' = updateMorIndex (ml+1) incl
return $ setMorMapDG (
Map.insert (ml+1) (toG_morphism incl')
(insLEdgeNubDG (n', n1, DGLink
, dgl_type = GlobalThm LeftOpen anno2 LeftOpen
, dgl_origin = DGExtension
return (sp1' : sps', JustNode nsig1, dg2, lg, opts, pos)