root/trunk/CASL/Morphism.hs @ 11213

Revision 11213, 21.0 kB (checked in by maeder, 11 months ago)

extended static symbol map checking

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1{- |
2Module      :  $Header$
3Description :  Symbols and signature morphisms for the CASL logic
4Copyright   :  (c) Christian Maeder, Till Mossakowski and Uni Bremen 2002-2004
5License     :  similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
6
7Maintainer  :  Christian.Maeder@dfki.de
8Stability   :  provisional
9Portability :  portable
10
11Symbols and signature morphisms for the CASL logic
12-}
13
14module CASL.Morphism where
15
16import CASL.Sign
17import CASL.AS_Basic_CASL
18
19import qualified Data.Map as Map
20import qualified Data.Set as Set
21import qualified Common.Lib.Rel as Rel
22import Common.Doc
23import Common.DocUtils
24import Common.Id
25import Common.Result
26
27import Control.Exception (assert)
28import Control.Monad
29
30type SymbolSet = Set.Set Symbol
31type SymbolMap = Map.Map Symbol Symbol
32
33data RawSymbol = ASymbol Symbol | AKindedSymb SYMB_KIND Id
34                 deriving (Show, Eq, Ord)
35
36instance GetRange RawSymbol where
37    getRange rs = case rs of
38        ASymbol s -> getRange s
39        AKindedSymb _ i -> getRange i
40
41type RawSymbolSet = Set.Set RawSymbol
42type RawSymbolMap = Map.Map RawSymbol RawSymbol
43
44type Sort_map = Map.Map SORT SORT
45-- always use the partial profile as key!
46type Op_map = Map.Map (Id, OpType) (Id, OpKind)
47type Pred_map = Map.Map (Id, PredType) Id
48
49data Morphism f e m = Morphism
50  { msource :: Sign f e
51  , mtarget :: Sign f e
52  , sort_map :: Sort_map
53  , op_map :: Op_map
54  , pred_map :: Pred_map
55  , extended_map :: m
56  } deriving (Show, Eq)
57
58data DefMorExt e = DefMorExt deriving (Show, Eq)
59
60emptyMorExt :: DefMorExt e
61emptyMorExt = DefMorExt
62
63instance Pretty (DefMorExt e) where
64  pretty _ = empty
65
66type CASLMor = Morphism () () ()
67
68isInclusionMorphism :: (m -> Bool) -> Morphism f e m -> Bool
69isInclusionMorphism f m = f (extended_map m) && Map.null (sort_map m)
70  && Map.null (pred_map m) && isInclOpMap (op_map m)
71
72mapSort :: Sort_map -> SORT -> SORT
73mapSort sorts s = Map.findWithDefault s s sorts
74
75mapOpType :: Sort_map -> OpType -> OpType
76mapOpType sorts t = if Map.null sorts then t else
77  t { opArgs = map (mapSort sorts) $ opArgs t
78    , opRes = mapSort sorts $ opRes t }
79
80mapOpTypeK :: Sort_map -> OpKind -> OpType -> OpType
81mapOpTypeK sorts k = makeTotal k . mapOpType sorts
82
83makeTotal :: OpKind -> OpType -> OpType
84makeTotal fk t = case fk of
85  Total -> t { opKind = Total }
86  _ -> t
87
88mapOpSym :: Sort_map -> Op_map -> (Id, OpType) -> (Id, OpType)
89mapOpSym sMap oMap (i, ot) = let mot = mapOpType sMap ot in
90  case Map.lookup (i, ot {opKind = Partial} ) oMap of
91    Nothing -> (i, mot)
92    Just (j, k) -> (j, makeTotal k mot)
93
94-- | Check if two OpTypes are equal modulo totality or partiality
95compatibleOpTypes :: OpType -> OpType -> Bool
96compatibleOpTypes ot1 ot2 = opArgs ot1 == opArgs ot2 && opRes ot1 == opRes ot2
97
98mapPredType :: Sort_map -> PredType -> PredType
99mapPredType sorts t = if Map.null sorts then t else
100  t { predArgs = map (mapSort sorts) $ predArgs t }
101
102mapPredSym :: Sort_map -> Pred_map -> (Id, PredType) -> (Id, PredType)
103mapPredSym sMap oMap (i, pt) =
104    (Map.findWithDefault i (i, pt) oMap, mapPredType sMap pt)
105
106embedMorphism :: m -> Sign f e -> Sign f e -> Morphism f e m
107embedMorphism extEm a b = Morphism
108  { msource = a
109  , mtarget = b
110  , sort_map = Map.empty
111  , op_map = Map.empty
112  , pred_map = Map.empty
113  , extended_map = extEm }
114
115symbTypeToKind :: SymbType -> SYMB_KIND
116symbTypeToKind st = case st of
117  OpAsItemType _ -> Ops_kind
118  PredAsItemType _ -> Preds_kind
119  SortAsItemType -> Sorts_kind
120
121symbolToRaw :: Symbol -> RawSymbol
122symbolToRaw = ASymbol
123
124idToRaw :: Id -> RawSymbol
125idToRaw = AKindedSymb Implicit
126
127rawSymName :: RawSymbol -> Id
128rawSymName rs = case rs of
129  ASymbol sym -> symName sym
130  AKindedSymb _ i -> i
131
132symOf :: Sign f e -> SymbolSet
133symOf sigma = let
134    sorts = Set.map idToSortSymbol $ sortSet sigma
135    ops = Set.fromList $
136      concatMap (\ (i, ts) -> map ( \ t -> idToOpSymbol i t) $ Set.toList ts)
137        $ Map.toList $ opMap sigma
138    preds = Set.fromList $
139       concatMap (\ (i, ts) -> map ( \ t -> idToPredSymbol i t)
140           $ Set.toList ts) $ Map.toList $ predMap sigma
141    in Set.unions [sorts, ops, preds]
142
143checkSymbList :: [SYMB_OR_MAP] -> [Diagnosis]
144checkSymbList l = case l of
145         Symb (Symb_id a) : Symb (Qual_id b t _) : r -> mkDiag Warning
146           ("profile '" ++ showDoc t "' does not apply to '"
147            ++ showId a "' but only to") b : checkSymbList r
148         _ : r -> checkSymbList r
149         [] -> []
150
151statSymbMapItems :: [SYMB_MAP_ITEMS] -> Result RawSymbolMap
152statSymbMapItems sl = do
153  let st (Symb_map_items kind l _) = do
154        appendDiags $ checkSymbList l
155        fmap concat $ mapM (symbOrMapToRaw kind) l
156      insertRsys m1 (rsy1, rsy2) = case Map.lookup rsy1 m1 of
157          Nothing -> return $ Map.insert rsy1 rsy2 m1
158          Just rsy3 -> if rsy2 == rsy3 then return m1 else
159              plain_error m1 ("Symbol " ++ showDoc rsy1 " mapped twice to "
160                ++ showDoc rsy2 " and " ++ showDoc rsy3 "") nullRange
161  ls <- mapM st sl
162  foldM insertRsys Map.empty (concat ls)
163
164symbOrMapToRaw :: SYMB_KIND -> SYMB_OR_MAP -> Result [(RawSymbol, RawSymbol)]
165symbOrMapToRaw k sm = do
166  case sm of
167    Symb s -> do
168      v <- symbToRaw k s
169      return [(v, v)]
170    Symb_map s t _ -> do
171      appendDiags $ case (s, t) of
172        (Symb_id a, Symb_id b) | a == b ->
173          [mkDiag Hint "unneeded identical mapping of" a]
174        _ -> []
175      w <- symbToRaw k s
176      x <- symbToRaw k t
177      let mkS = AKindedSymb Sorts_kind
178      case (s, t) of
179        (Qual_id _ t1 _, Qual_id _ t2 _) -> case (t1, t2) of
180          (O_type (Op_type k1 args1 res1 _), O_type (Op_type k2 args2 res2 _))
181            | length args1 == length args2 && k2 <= k1 ->
182            return $ (w, x) : (mkS res1, mkS res2)
183              : zipWith (\ s1 s2 -> (mkS s1, mkS s2)) args1 args2
184          (P_type (Pred_type args1 _), P_type (Pred_type args2 _))
185            | length args1 == length args2 ->
186            return $ (w, x)
187              : zipWith (\ s1 s2 -> (mkS s1, mkS s2)) args1 args2
188          (O_type (Op_type Partial [] res1 _), A_type s2) ->
189            return [(w, x), (mkS res1, mkS s2)]
190          _ -> fail $ "profiles '" ++ showDoc t1 "' and '"
191               ++ showDoc t2 "' do not match"
192        _ -> return [(w, x)]
193
194statSymbItems :: [SYMB_ITEMS] -> Result [RawSymbol]
195statSymbItems sl =
196  let st (Symb_items kind l _) = do
197        appendDiags $ checkSymbList $ map Symb l
198        mapM (symbToRaw kind) l
199  in fmap concat (mapM st sl)
200
201symbToRaw :: SYMB_KIND -> SYMB -> Result RawSymbol
202symbToRaw k si = case si of
203  Symb_id idt -> return $ AKindedSymb k idt
204  Qual_id idt t _ -> typedSymbKindToRaw k idt t
205
206typedSymbKindToRaw :: SYMB_KIND -> Id -> TYPE -> Result RawSymbol
207typedSymbKindToRaw k idt t = let
208     err = plain_error (AKindedSymb Implicit idt)
209              (showDoc idt ":" ++ showDoc t
210               "does not have kind" ++ showDoc k "") nullRange
211     aSymb = ASymbol $ case t of
212       O_type ot -> idToOpSymbol idt $ toOpType ot
213       P_type pt -> idToPredSymbol idt $ toPredType pt
214             -- in case of ambiguity, return a constant function type
215             -- this deviates from the CASL summary !!!
216       A_type s ->
217           let ot = OpType {opKind = Total, opArgs = [], opRes = s}
218           in idToOpSymbol idt ot
219    in case k of
220    Implicit -> case t of
221      A_type _ -> do
222          appendDiags [mkDiag Warning "qualify name as pred or op" idt]
223          return aSymb
224      _ -> return aSymb
225    Sorts_kind -> err
226    Ops_kind -> case t of
227        P_type _ -> err
228        _ -> return aSymb
229    Preds_kind -> case t of
230        O_type _ -> err
231        A_type s -> return $ ASymbol $
232                    let pt = PredType {predArgs = [s]}
233                    in idToPredSymbol idt pt
234        P_type _ -> return aSymb
235
236symbMapToMorphism :: m -> Sign f e -> Sign f e
237                  -> SymbolMap -> Result (Morphism f e m)
238symbMapToMorphism extEm sigma1 sigma2 smap = let
239  sort_map1 = Set.fold mapMSort Map.empty (sortSet sigma1)
240  mapMSort s m =
241    case Map.lookup Symbol {symName = s, symbType = SortAsItemType} smap
242    of Just sym -> let t = symName sym in if s == t then m else
243                           Map.insert s t m
244       Nothing -> m
245  op_map1 = Map.foldWithKey mapOp Map.empty (opMap sigma1)
246  pred_map1 = Map.foldWithKey mapPred Map.empty (predMap sigma1)
247  mapOp i ots m = Set.fold (insOp i) m ots
248  insOp i ot m =
249    case Map.lookup Symbol {symName = i, symbType = OpAsItemType ot} smap
250    of Just sym -> let j = symName sym in case symbType sym of
251         OpAsItemType oty -> let k = opKind oty in
252            if j == i && opKind ot == k then m
253            else Map.insert (i, ot {opKind = Partial}) (j, k) m
254         _ -> m
255       _ -> m
256  mapPred i pts m = Set.fold (insPred i) m pts
257  insPred i pt m =
258    case Map.lookup Symbol {symName = i, symbType = PredAsItemType pt} smap
259    of Just sym -> let j = symName sym in  case symbType sym of
260         PredAsItemType _ -> if i == j then m else Map.insert (i, pt) j m
261         _ -> m
262       _ -> m
263  in return (embedMorphism extEm sigma1 sigma2)
264     { sort_map = sort_map1
265     , op_map = op_map1
266     , pred_map = pred_map1 }
267
268morphismToSymbMap :: Morphism f e m -> SymbolMap
269morphismToSymbMap = morphismToSymbMapAux False
270
271morphismToSymbMapAux :: Bool -> Morphism f e m -> SymbolMap
272morphismToSymbMapAux b mor = let
273    src = msource mor
274    sorts = sort_map mor
275    ops = op_map mor
276    preds = pred_map mor
277    sortSymMap = Set.fold
278      (\ s -> let t = mapSort sorts s in
279         if b && s == t then id else
280             Map.insert (idToSortSymbol s) $ idToSortSymbol t)
281      Map.empty $ sortSet src
282    opSymMap = Map.foldWithKey
283      ( \ i s m -> Set.fold
284        ( \ t -> let (j, k) = mapOpSym sorts ops (i, t) in
285                 if b && i == j && opKind k == opKind t then id else
286                     Map.insert (idToOpSymbol i t) $ idToOpSymbol j k)
287        m s) Map.empty $ opMap src
288    predSymMap = Map.foldWithKey
289      ( \ i s m -> Set.fold
290        ( \ t -> let (j, k) = mapPredSym sorts preds (i, t) in
291                 if b && i == j then id else
292                     Map.insert (idToPredSymbol i t) $ idToPredSymbol j k)
293        m s) Map.empty $ predMap src
294  in foldr Map.union sortSymMap [opSymMap, predSymMap]
295
296matches :: Symbol -> RawSymbol -> Bool
297matches x@(Symbol idt k) rs = case rs of
298    ASymbol y -> x == y
299    AKindedSymb rk di -> let res = idt == di in case (k, rk) of
300        (_, Implicit) -> res
301        (SortAsItemType, Sorts_kind) -> res
302        (OpAsItemType _, Ops_kind) -> res
303        (PredAsItemType _, Preds_kind) -> res
304        _ -> False
305
306idMor :: m -> Sign f e -> Morphism f e m
307idMor extEm sigma = embedMorphism extEm sigma sigma
308
309composeM :: (Eq e, Eq f) => (m -> m -> Result m)
310         -> Morphism f e m -> Morphism f e m -> Result (Morphism f e m)
311composeM comp mor1 mor2 = if mtarget mor1 == msource mor2 then do
312  let sMap1 = sort_map mor1
313      src = msource mor1
314      tar = mtarget mor2
315      oMap1 = op_map mor1
316      pMap1 = pred_map mor1
317      sMap2 = sort_map mor2
318      oMap2 = op_map mor2
319      pMap2 = pred_map mor2
320      sMap = if Map.null sMap2 then sMap1 else Set.fold ( \ i ->
321                               let j = mapSort sMap2 (mapSort sMap1 i) in
322                               if i == j then id else Map.insert i j)
323                Map.empty $ sortSet src
324      oMap = if Map.null oMap2 then oMap1 else
325                 Map.foldWithKey ( \ i t m ->
326                   Set.fold ( \ ot ->
327                       let (ni, nt) = mapOpSym sMap2 oMap2 $
328                                      mapOpSym sMap1 oMap1 (i, ot)
329                           k = opKind nt
330                       in assert (mapOpTypeK sMap k ot == nt) $
331                          if i == ni && opKind ot == k then id else
332                          Map.insert (i, ot {opKind = Partial }) (ni, k)) m t)
333                     Map.empty $ opMap src
334      pMap = if Map.null pMap2 then pMap1 else
335                 Map.foldWithKey ( \ i t m ->
336                   Set.fold ( \ pt ->
337                       let (ni, nt) = mapPredSym sMap2 pMap2 $
338                                     mapPredSym sMap1 pMap1 (i, pt)
339                       in assert (mapPredType sMap pt == nt) $
340                       if i == ni then id else Map.insert (i, pt) ni) m t)
341                      Map.empty $ predMap src
342  extComp <- comp (extended_map mor1) $ extended_map mor2
343  let emb = embedMorphism extComp src tar
344  return $ emb
345     { sort_map = sMap
346     , op_map = oMap
347     , pred_map = pMap }
348 else fail "target of first and source of second morphism are different"
349
350legalSign :: Sign f e -> Bool
351legalSign sigma =
352  Map.foldWithKey (\s sset b -> b && legalSort s && all legalSort
353                                (Set.toList sset))
354                  True (Rel.toMap (sortRel sigma))
355  && Map.fold (\ts b -> b && all legalOpType (Set.toList ts))
356              True (opMap sigma)
357  && Map.fold (\ts b -> b && all legalPredType (Set.toList ts))
358              True (predMap sigma)
359  where sorts = sortSet sigma
360        legalSort s = Set.member s sorts
361        legalOpType t = legalSort (opRes t)
362                        && all legalSort (opArgs t)
363        legalPredType = all legalSort . predArgs
364
365-- | the image of a signature morphism
366imageOfMorphism :: Morphism f e m  -> Sign f e
367imageOfMorphism mor =
368  let src = msource mor
369      sm = sort_map mor
370      om = op_map mor
371      ms = mapSort sm
372      msorts = Set.map ms
373  in (mtarget mor)
374  { sortSet = msorts $ sortSet src
375  , sortRel = Rel.map ms $ sortRel src
376  , emptySortSet = msorts $ emptySortSet src
377  , opMap = inducedOpMap sm om $ opMap src
378  , assocOps = inducedOpMap sm om $ assocOps src
379  , predMap = inducedPredMap sm (pred_map mor) $ predMap src }
380
381inducedOpMap :: Sort_map -> Op_map -> OpMap -> OpMap
382inducedOpMap sm fm = Map.foldWithKey
383  ( \ i -> flip $ Set.fold ( \ ot ->
384      let (j, nt) = mapOpSym sm fm (i, ot)
385      in Rel.setInsert j nt)) Map.empty
386
387inducedPredMap :: Sort_map -> Pred_map -> Map.Map Id (Set.Set PredType)
388               -> Map.Map Id (Set.Set PredType)
389inducedPredMap sm pm = Map.foldWithKey
390  ( \ i -> flip $ Set.fold ( \ ot ->
391      let (j, nt) = mapPredSym sm pm (i, ot)
392      in Rel.setInsert j nt)) Map.empty
393
394legalMor :: Morphism f e m -> Bool
395legalMor mor =
396  let s1 = msource mor
397      s2 = mtarget mor
398      sm = sort_map mor
399      msorts = Set.map $ mapSort sm
400  in legalSign s1
401  && Set.isSubsetOf (msorts $ sortSet s1) (sortSet s2)
402  && Set.isSubsetOf (msorts $ emptySortSet s1) (emptySortSet s2)
403  && isSubOpMap (inducedOpMap sm (op_map mor) $ opMap s1) (opMap s2)
404  && isSubMapSet (inducedPredMap sm (pred_map mor) $ predMap s1) (predMap s2)
405  && legalSign s2
406
407isInclOpMap :: Op_map -> Bool
408isInclOpMap = all (\ ((i, _), (j, k)) -> i == j && k == Total) . Map.toList
409
410idOrInclMorphism :: (e -> e -> Bool) -> Morphism f e m -> Morphism f e m
411idOrInclMorphism isSubExt m =
412  let src = msource m
413      tar = mtarget m
414  in if isSubSig isSubExt tar src then m
415     else let diffOpMap = diffMapSet (opMap src) $ opMap tar in
416          m { op_map = Map.fromList $ concatMap (\ (i, s) ->
417              map (\ t -> ((i, t), (i, Total)))
418                 $ Set.toList s) $ Map.toList diffOpMap }
419
420sigInclusion :: (Pretty f, Pretty e)
421             => m -- ^ computed extended morphism
422             -> (e -> e -> Bool) -- ^ subsignature test of extensions
423             -> (e -> e -> e) -- ^ difference of signature extensions
424             -> Sign f e -> Sign f e -> Result (Morphism f e m)
425sigInclusion extEm isSubExt diffExt sigma1 sigma2 =
426  if isSubSig isSubExt sigma1 sigma2 then
427     return $ idOrInclMorphism isSubExt $ embedMorphism extEm sigma1 sigma2
428  else Result [Diag Error
429          ("Attempt to construct inclusion between non-subsignatures:\n"
430           ++ showDoc (diffSig diffExt sigma1 sigma2) "") nullRange] Nothing
431
432addSigM :: Monad m => (e -> e -> m e) -> Sign f e -> Sign f e -> m (Sign f e)
433addSigM f a b = do
434  e <- f (extendedInfo a) $ extendedInfo b
435  return $ addSig (const $ const e) a b
436
437morphismUnion :: (m -> m -> m) -- ^ join morphism extensions
438              -> (e -> e -> e) -- ^ join signature extensions
439              -> Morphism f e m -> Morphism f e m -> Result (Morphism f e m)
440morphismUnion uniteM addSigExt =
441    morphismUnionM uniteM (\ e -> return . addSigExt e)
442
443morphismUnionM :: (m -> m -> m)  -- ^ join morphism extensions
444              -> (e -> e -> Result e) -- ^ join signature extensions
445              -> Morphism f e m -> Morphism f e m -> Result (Morphism f e m)
446-- consider identity mappings but filter them eventually
447morphismUnionM uniteM addSigExt mor1 mor2 =
448  let smap1 = sort_map mor1
449      smap2 = sort_map mor2
450      s1 = msource mor1
451      s2 = msource mor2
452      us1 = Set.difference (sortSet s1) $ Map.keysSet smap1
453      us2 = Set.difference (sortSet s2) $ Map.keysSet smap2
454      omap1 = op_map mor1
455      omap2 = op_map mor2
456      uo1 = foldr delOp (opMap s1) $ Map.keys omap1
457      uo2 = foldr delOp (opMap s2) $ Map.keys omap2
458      delOp (n, ot) m = diffMapSet m $ Map.singleton n $
459                    Set.fromList [ot {opKind = Partial}, ot {opKind = Total}]
460      uo = addOpMapSet uo1 uo2
461      pmap1 = pred_map mor1
462      pmap2 = pred_map mor2
463      up1 = foldr delPred (predMap s1) $ Map.keys pmap1
464      up2 = foldr delPred (predMap s2) $ Map.keys pmap2
465      up = addMapSet up1 up2
466      delPred (n, pt) m = diffMapSet m $ Map.singleton n $ Set.singleton pt
467      (sds, smap) = foldr ( \ (i, j) (ds, m) -> case Map.lookup i m of
468          Nothing -> (ds, Map.insert i j m)
469          Just k -> if j == k then (ds, m) else
470              (Diag Error
471               ("incompatible mapping of sort " ++ showId i " to "
472                ++ showId j " and " ++ showId k "")
473               nullRange : ds, m)) ([], smap1)
474          (Map.toList smap2 ++ map (\ a -> (a, a))
475                      (Set.toList $ Set.union us1 us2))
476      (ods, omap) = foldr ( \ (isc@(i, ot), jsc@(j, t)) (ds, m) ->
477          case Map.lookup isc m of
478          Nothing -> (ds, Map.insert isc jsc m)
479          Just (k, p) -> if j == k then if p == t then (ds, m)
480                            else (ds, Map.insert isc (j, Total) m) else
481              (Diag Error
482               ("incompatible mapping of op " ++ showId i ":"
483                ++ showDoc ot { opKind = t } " to "
484                ++ showId j " and " ++ showId k "") nullRange : ds, m))
485           (sds, omap1) (Map.toList omap2 ++ concatMap
486              ( \ (a, s) -> map ( \ ot -> ((a, ot {opKind = Partial}),
487                                           (a, opKind ot)))
488              $ Set.toList s) (Map.toList uo))
489      (pds, pmap) = foldr ( \ (isc@(i, pt), j) (ds, m) ->
490          case Map.lookup isc m of
491          Nothing -> (ds, Map.insert isc j m)
492          Just k -> if j == k then (ds, m) else
493              (Diag Error
494               ("incompatible mapping of pred " ++ showId i ":"
495                ++ showDoc pt " to " ++ showId j " and "
496                ++ showId k "") nullRange : ds, m)) (ods, pmap1)
497          (Map.toList pmap2 ++ concatMap ( \ (a, s) -> map
498              ( \ pt -> ((a, pt), a)) $ Set.toList s) (Map.toList up))
499  in if null pds then do
500    s3 <- addSigM addSigExt s1 s2
501    s4 <- addSigM addSigExt (mtarget mor1) $ mtarget mor2
502    let o3 = opMap s3
503    return
504      (embedMorphism (uniteM (extended_map mor1) $ extended_map mor2) s3 s4)
505      { sort_map = Map.filterWithKey (/=) smap
506      , op_map = Map.filterWithKey
507        (\ (i, ot) (j, k) -> i /= j || k == Total && Set.member ot
508         (Map.findWithDefault Set.empty i o3)) omap
509      , pred_map = Map.filterWithKey (\ (i, _) j -> i /= j) pmap }
510    else Result pds Nothing
511
512isSortInjective :: Morphism f e m -> Bool
513isSortInjective m =
514    let ss = sortSet $ msource m
515    in Set.size ss == Set.size (Set.map (mapSort $ sort_map m) ss)
516
517sumSize :: Map.Map a (Set.Set b) -> Int
518sumSize = sum . map Set.size . Map.elems
519
520-- morphism extension m is not considered here
521isInjective :: Morphism f e m -> Bool
522isInjective m = isSortInjective m && let
523    src = msource m
524    sm = sort_map m
525    os = opMap src
526    ps = predMap src
527    in sumSize os == sumSize (inducedOpMap sm (op_map m) os)
528       && sumSize ps == sumSize (inducedPredMap sm (pred_map m) ps)
529
530instance Pretty RawSymbol where
531  pretty rsym = case rsym of
532    ASymbol sy -> pretty sy
533    AKindedSymb k i -> pretty k <+> pretty i
534
535printMorphism :: (f -> Doc) -> (e -> Doc) -> (m -> Doc) -> Morphism f e m
536              -> Doc
537printMorphism fF fE fM mor =
538    let src = msource mor
539        tar = mtarget mor
540        ops = op_map mor
541        prSig s = specBraces (space <> printSign fF fE s)
542        srcD = prSig src
543    in if isInclusionMorphism (const True) mor then
544           if isSubSig (\ _ _ -> True) tar src then
545               fsep [text "identity morphism over", srcD]
546           else fsep
547      [ text "inclusion morphism of", srcD
548      , fsep $ if Map.null ops then
549          [ text "extended with"
550          , pretty $ Set.difference (symOf tar) $ symOf src ]
551        else
552          [ text "by totalizing"
553          , pretty $ Set.map (uncurry idToOpSymbol) $ Map.keysSet ops ]]
554    else fsep
555      [ pretty (morphismToSymbMapAux True mor)
556          $+$ fM (extended_map mor)
557      , colon <+> srcD, mapsto <+> prSig tar ]
558
559instance (Pretty e, Pretty f, Pretty m) =>
560    Pretty (Morphism f e m) where
561       pretty = printMorphism pretty pretty pretty
Note: See TracBrowser for help on using the browser.