root/trunk/CASL/Morphism.hs @ 11214

Revision 11214, 21.2 kB (checked in by maeder, 11 months ago)

ignore partiality in symbol mappings

  • 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 _ args1 res1 _), O_type (Op_type _ args2 res2 _))
181            | length args1 == length args2 -> -- ignore partiality
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 _ [] res1 _), A_type s2) ->
189            return [(w, x), (mkS res1, mkS s2)]
190          (A_type s1, O_type (Op_type _ [] res2 _)) ->
191            return [(w, x), (mkS s1, mkS res2)]
192          (A_type s1, A_type s2) ->
193            return [(w, x), (mkS s1, mkS s2)]
194          _ -> fail $ "profiles '" ++ showDoc t1 "' and '"
195               ++ showDoc t2 "' do not match"
196        _ -> return [(w, x)]
197
198statSymbItems :: [SYMB_ITEMS] -> Result [RawSymbol]
199statSymbItems sl =
200  let st (Symb_items kind l _) = do
201        appendDiags $ checkSymbList $ map Symb l
202        mapM (symbToRaw kind) l
203  in fmap concat (mapM st sl)
204
205symbToRaw :: SYMB_KIND -> SYMB -> Result RawSymbol
206symbToRaw k si = case si of
207  Symb_id idt -> return $ AKindedSymb k idt
208  Qual_id idt t _ -> typedSymbKindToRaw k idt t
209
210typedSymbKindToRaw :: SYMB_KIND -> Id -> TYPE -> Result RawSymbol
211typedSymbKindToRaw k idt t = let
212     err = plain_error (AKindedSymb Implicit idt)
213              (showDoc idt ":" ++ showDoc t
214               "does not have kind" ++ showDoc k "") nullRange
215     aSymb = ASymbol $ case t of
216       O_type ot -> idToOpSymbol idt $ toOpType ot
217       P_type pt -> idToPredSymbol idt $ toPredType pt
218             -- in case of ambiguity, return a constant function type
219             -- this deviates from the CASL summary !!!
220       A_type s ->
221           let ot = OpType {opKind = Total, opArgs = [], opRes = s}
222           in idToOpSymbol idt ot
223    in case k of
224    Implicit -> case t of
225      A_type _ -> do
226          appendDiags [mkDiag Warning "qualify name as pred or op" idt]
227          return aSymb
228      _ -> return aSymb
229    Sorts_kind -> err
230    Ops_kind -> case t of
231        P_type _ -> err
232        _ -> return aSymb
233    Preds_kind -> case t of
234        O_type _ -> err
235        A_type s -> return $ ASymbol $
236                    let pt = PredType {predArgs = [s]}
237                    in idToPredSymbol idt pt
238        P_type _ -> return aSymb
239
240symbMapToMorphism :: m -> Sign f e -> Sign f e
241                  -> SymbolMap -> Result (Morphism f e m)
242symbMapToMorphism extEm sigma1 sigma2 smap = let
243  sort_map1 = Set.fold mapMSort Map.empty (sortSet sigma1)
244  mapMSort s m =
245    case Map.lookup Symbol {symName = s, symbType = SortAsItemType} smap
246    of Just sym -> let t = symName sym in if s == t then m else
247                           Map.insert s t m
248       Nothing -> m
249  op_map1 = Map.foldWithKey mapOp Map.empty (opMap sigma1)
250  pred_map1 = Map.foldWithKey mapPred Map.empty (predMap sigma1)
251  mapOp i ots m = Set.fold (insOp i) m ots
252  insOp i ot m =
253    case Map.lookup Symbol {symName = i, symbType = OpAsItemType ot} smap
254    of Just sym -> let j = symName sym in case symbType sym of
255         OpAsItemType oty -> let k = opKind oty in
256            if j == i && opKind ot == k then m
257            else Map.insert (i, ot {opKind = Partial}) (j, k) m
258         _ -> m
259       _ -> m
260  mapPred i pts m = Set.fold (insPred i) m pts
261  insPred i pt m =
262    case Map.lookup Symbol {symName = i, symbType = PredAsItemType pt} smap
263    of Just sym -> let j = symName sym in  case symbType sym of
264         PredAsItemType _ -> if i == j then m else Map.insert (i, pt) j m
265         _ -> m
266       _ -> m
267  in return (embedMorphism extEm sigma1 sigma2)
268     { sort_map = sort_map1
269     , op_map = op_map1
270     , pred_map = pred_map1 }
271
272morphismToSymbMap :: Morphism f e m -> SymbolMap
273morphismToSymbMap = morphismToSymbMapAux False
274
275morphismToSymbMapAux :: Bool -> Morphism f e m -> SymbolMap
276morphismToSymbMapAux b mor = let
277    src = msource mor
278    sorts = sort_map mor
279    ops = op_map mor
280    preds = pred_map mor
281    sortSymMap = Set.fold
282      (\ s -> let t = mapSort sorts s in
283         if b && s == t then id else
284             Map.insert (idToSortSymbol s) $ idToSortSymbol t)
285      Map.empty $ sortSet src
286    opSymMap = Map.foldWithKey
287      ( \ i s m -> Set.fold
288        ( \ t -> let (j, k) = mapOpSym sorts ops (i, t) in
289                 if b && i == j && opKind k == opKind t then id else
290                     Map.insert (idToOpSymbol i t) $ idToOpSymbol j k)
291        m s) Map.empty $ opMap src
292    predSymMap = Map.foldWithKey
293      ( \ i s m -> Set.fold
294        ( \ t -> let (j, k) = mapPredSym sorts preds (i, t) in
295                 if b && i == j then id else
296                     Map.insert (idToPredSymbol i t) $ idToPredSymbol j k)
297        m s) Map.empty $ predMap src
298  in foldr Map.union sortSymMap [opSymMap, predSymMap]
299
300matches :: Symbol -> RawSymbol -> Bool
301matches x@(Symbol idt k) rs = case rs of
302    ASymbol y -> x == y
303    AKindedSymb rk di -> let res = idt == di in case (k, rk) of
304        (_, Implicit) -> res
305        (SortAsItemType, Sorts_kind) -> res
306        (OpAsItemType _, Ops_kind) -> res
307        (PredAsItemType _, Preds_kind) -> res
308        _ -> False
309
310idMor :: m -> Sign f e -> Morphism f e m
311idMor extEm sigma = embedMorphism extEm sigma sigma
312
313composeM :: (Eq e, Eq f) => (m -> m -> Result m)
314         -> Morphism f e m -> Morphism f e m -> Result (Morphism f e m)
315composeM comp mor1 mor2 = if mtarget mor1 == msource mor2 then do
316  let sMap1 = sort_map mor1
317      src = msource mor1
318      tar = mtarget mor2
319      oMap1 = op_map mor1
320      pMap1 = pred_map mor1
321      sMap2 = sort_map mor2
322      oMap2 = op_map mor2
323      pMap2 = pred_map mor2
324      sMap = if Map.null sMap2 then sMap1 else Set.fold ( \ i ->
325                               let j = mapSort sMap2 (mapSort sMap1 i) in
326                               if i == j then id else Map.insert i j)
327                Map.empty $ sortSet src
328      oMap = if Map.null oMap2 then oMap1 else
329                 Map.foldWithKey ( \ i t m ->
330                   Set.fold ( \ ot ->
331                       let (ni, nt) = mapOpSym sMap2 oMap2 $
332                                      mapOpSym sMap1 oMap1 (i, ot)
333                           k = opKind nt
334                       in assert (mapOpTypeK sMap k ot == nt) $
335                          if i == ni && opKind ot == k then id else
336                          Map.insert (i, ot {opKind = Partial }) (ni, k)) m t)
337                     Map.empty $ opMap src
338      pMap = if Map.null pMap2 then pMap1 else
339                 Map.foldWithKey ( \ i t m ->
340                   Set.fold ( \ pt ->
341                       let (ni, nt) = mapPredSym sMap2 pMap2 $
342                                     mapPredSym sMap1 pMap1 (i, pt)
343                       in assert (mapPredType sMap pt == nt) $
344                       if i == ni then id else Map.insert (i, pt) ni) m t)
345                      Map.empty $ predMap src
346  extComp <- comp (extended_map mor1) $ extended_map mor2
347  let emb = embedMorphism extComp src tar
348  return $ emb
349     { sort_map = sMap
350     , op_map = oMap
351     , pred_map = pMap }
352 else fail "target of first and source of second morphism are different"
353
354legalSign :: Sign f e -> Bool
355legalSign sigma =
356  Map.foldWithKey (\s sset b -> b && legalSort s && all legalSort
357                                (Set.toList sset))
358                  True (Rel.toMap (sortRel sigma))
359  && Map.fold (\ts b -> b && all legalOpType (Set.toList ts))
360              True (opMap sigma)
361  && Map.fold (\ts b -> b && all legalPredType (Set.toList ts))
362              True (predMap sigma)
363  where sorts = sortSet sigma
364        legalSort s = Set.member s sorts
365        legalOpType t = legalSort (opRes t)
366                        && all legalSort (opArgs t)
367        legalPredType = all legalSort . predArgs
368
369-- | the image of a signature morphism
370imageOfMorphism :: Morphism f e m  -> Sign f e
371imageOfMorphism mor =
372  let src = msource mor
373      sm = sort_map mor
374      om = op_map mor
375      ms = mapSort sm
376      msorts = Set.map ms
377  in (mtarget mor)
378  { sortSet = msorts $ sortSet src
379  , sortRel = Rel.map ms $ sortRel src
380  , emptySortSet = msorts $ emptySortSet src
381  , opMap = inducedOpMap sm om $ opMap src
382  , assocOps = inducedOpMap sm om $ assocOps src
383  , predMap = inducedPredMap sm (pred_map mor) $ predMap src }
384
385inducedOpMap :: Sort_map -> Op_map -> OpMap -> OpMap
386inducedOpMap sm fm = Map.foldWithKey
387  ( \ i -> flip $ Set.fold ( \ ot ->
388      let (j, nt) = mapOpSym sm fm (i, ot)
389      in Rel.setInsert j nt)) Map.empty
390
391inducedPredMap :: Sort_map -> Pred_map -> Map.Map Id (Set.Set PredType)
392               -> Map.Map Id (Set.Set PredType)
393inducedPredMap sm pm = Map.foldWithKey
394  ( \ i -> flip $ Set.fold ( \ ot ->
395      let (j, nt) = mapPredSym sm pm (i, ot)
396      in Rel.setInsert j nt)) Map.empty
397
398legalMor :: Morphism f e m -> Bool
399legalMor mor =
400  let s1 = msource mor
401      s2 = mtarget mor
402      sm = sort_map mor
403      msorts = Set.map $ mapSort sm
404  in legalSign s1
405  && Set.isSubsetOf (msorts $ sortSet s1) (sortSet s2)
406  && Set.isSubsetOf (msorts $ emptySortSet s1) (emptySortSet s2)
407  && isSubOpMap (inducedOpMap sm (op_map mor) $ opMap s1) (opMap s2)
408  && isSubMapSet (inducedPredMap sm (pred_map mor) $ predMap s1) (predMap s2)
409  && legalSign s2
410
411isInclOpMap :: Op_map -> Bool
412isInclOpMap = all (\ ((i, _), (j, k)) -> i == j && k == Total) . Map.toList
413
414idOrInclMorphism :: (e -> e -> Bool) -> Morphism f e m -> Morphism f e m
415idOrInclMorphism isSubExt m =
416  let src = msource m
417      tar = mtarget m
418  in if isSubSig isSubExt tar src then m
419     else let diffOpMap = diffMapSet (opMap src) $ opMap tar in
420          m { op_map = Map.fromList $ concatMap (\ (i, s) ->
421              map (\ t -> ((i, t), (i, Total)))
422                 $ Set.toList s) $ Map.toList diffOpMap }
423
424sigInclusion :: (Pretty f, Pretty e)
425             => m -- ^ computed extended morphism
426             -> (e -> e -> Bool) -- ^ subsignature test of extensions
427             -> (e -> e -> e) -- ^ difference of signature extensions
428             -> Sign f e -> Sign f e -> Result (Morphism f e m)
429sigInclusion extEm isSubExt diffExt sigma1 sigma2 =
430  if isSubSig isSubExt sigma1 sigma2 then
431     return $ idOrInclMorphism isSubExt $ embedMorphism extEm sigma1 sigma2
432  else Result [Diag Error
433          ("Attempt to construct inclusion between non-subsignatures:\n"
434           ++ showDoc (diffSig diffExt sigma1 sigma2) "") nullRange] Nothing
435
436addSigM :: Monad m => (e -> e -> m e) -> Sign f e -> Sign f e -> m (Sign f e)
437addSigM f a b = do
438  e <- f (extendedInfo a) $ extendedInfo b
439  return $ addSig (const $ const e) a b
440
441morphismUnion :: (m -> m -> m) -- ^ join morphism extensions
442              -> (e -> e -> e) -- ^ join signature extensions
443              -> Morphism f e m -> Morphism f e m -> Result (Morphism f e m)
444morphismUnion uniteM addSigExt =
445    morphismUnionM uniteM (\ e -> return . addSigExt e)
446
447morphismUnionM :: (m -> m -> m)  -- ^ join morphism extensions
448              -> (e -> e -> Result e) -- ^ join signature extensions
449              -> Morphism f e m -> Morphism f e m -> Result (Morphism f e m)
450-- consider identity mappings but filter them eventually
451morphismUnionM uniteM addSigExt mor1 mor2 =
452  let smap1 = sort_map mor1
453      smap2 = sort_map mor2
454      s1 = msource mor1
455      s2 = msource mor2
456      us1 = Set.difference (sortSet s1) $ Map.keysSet smap1
457      us2 = Set.difference (sortSet s2) $ Map.keysSet smap2
458      omap1 = op_map mor1
459      omap2 = op_map mor2
460      uo1 = foldr delOp (opMap s1) $ Map.keys omap1
461      uo2 = foldr delOp (opMap s2) $ Map.keys omap2
462      delOp (n, ot) m = diffMapSet m $ Map.singleton n $
463                    Set.fromList [ot {opKind = Partial}, ot {opKind = Total}]
464      uo = addOpMapSet uo1 uo2
465      pmap1 = pred_map mor1
466      pmap2 = pred_map mor2
467      up1 = foldr delPred (predMap s1) $ Map.keys pmap1
468      up2 = foldr delPred (predMap s2) $ Map.keys pmap2
469      up = addMapSet up1 up2
470      delPred (n, pt) m = diffMapSet m $ Map.singleton n $ Set.singleton pt
471      (sds, smap) = foldr ( \ (i, j) (ds, m) -> case Map.lookup i m of
472          Nothing -> (ds, Map.insert i j m)
473          Just k -> if j == k then (ds, m) else
474              (Diag Error
475               ("incompatible mapping of sort " ++ showId i " to "
476                ++ showId j " and " ++ showId k "")
477               nullRange : ds, m)) ([], smap1)
478          (Map.toList smap2 ++ map (\ a -> (a, a))
479                      (Set.toList $ Set.union us1 us2))
480      (ods, omap) = foldr ( \ (isc@(i, ot), jsc@(j, t)) (ds, m) ->
481          case Map.lookup isc m of
482          Nothing -> (ds, Map.insert isc jsc m)
483          Just (k, p) -> if j == k then if p == t then (ds, m)
484                            else (ds, Map.insert isc (j, Total) m) else
485              (Diag Error
486               ("incompatible mapping of op " ++ showId i ":"
487                ++ showDoc ot { opKind = t } " to "
488                ++ showId j " and " ++ showId k "") nullRange : ds, m))
489           (sds, omap1) (Map.toList omap2 ++ concatMap
490              ( \ (a, s) -> map ( \ ot -> ((a, ot {opKind = Partial}),
491                                           (a, opKind ot)))
492              $ Set.toList s) (Map.toList uo))
493      (pds, pmap) = foldr ( \ (isc@(i, pt), j) (ds, m) ->
494          case Map.lookup isc m of
495          Nothing -> (ds, Map.insert isc j m)
496          Just k -> if j == k then (ds, m) else
497              (Diag Error
498               ("incompatible mapping of pred " ++ showId i ":"
499                ++ showDoc pt " to " ++ showId j " and "
500                ++ showId k "") nullRange : ds, m)) (ods, pmap1)
501          (Map.toList pmap2 ++ concatMap ( \ (a, s) -> map
502              ( \ pt -> ((a, pt), a)) $ Set.toList s) (Map.toList up))
503  in if null pds then do
504    s3 <- addSigM addSigExt s1 s2
505    s4 <- addSigM addSigExt (mtarget mor1) $ mtarget mor2
506    let o3 = opMap s3
507    return
508      (embedMorphism (uniteM (extended_map mor1) $ extended_map mor2) s3 s4)
509      { sort_map = Map.filterWithKey (/=) smap
510      , op_map = Map.filterWithKey
511        (\ (i, ot) (j, k) -> i /= j || k == Total && Set.member ot
512         (Map.findWithDefault Set.empty i o3)) omap
513      , pred_map = Map.filterWithKey (\ (i, _) j -> i /= j) pmap }
514    else Result pds Nothing
515
516isSortInjective :: Morphism f e m -> Bool
517isSortInjective m =
518    let ss = sortSet $ msource m
519    in Set.size ss == Set.size (Set.map (mapSort $ sort_map m) ss)
520
521sumSize :: Map.Map a (Set.Set b) -> Int
522sumSize = sum . map Set.size . Map.elems
523
524-- morphism extension m is not considered here
525isInjective :: Morphism f e m -> Bool
526isInjective m = isSortInjective m && let
527    src = msource m
528    sm = sort_map m
529    os = opMap src
530    ps = predMap src
531    in sumSize os == sumSize (inducedOpMap sm (op_map m) os)
532       && sumSize ps == sumSize (inducedPredMap sm (pred_map m) ps)
533
534instance Pretty RawSymbol where
535  pretty rsym = case rsym of
536    ASymbol sy -> pretty sy
537    AKindedSymb k i -> pretty k <+> pretty i
538
539printMorphism :: (f -> Doc) -> (e -> Doc) -> (m -> Doc) -> Morphism f e m
540              -> Doc
541printMorphism fF fE fM mor =
542    let src = msource mor
543        tar = mtarget mor
544        ops = op_map mor
545        prSig s = specBraces (space <> printSign fF fE s)
546        srcD = prSig src
547    in if isInclusionMorphism (const True) mor then
548           if isSubSig (\ _ _ -> True) tar src then
549               fsep [text "identity morphism over", srcD]
550           else fsep
551      [ text "inclusion morphism of", srcD
552      , fsep $ if Map.null ops then
553          [ text "extended with"
554          , pretty $ Set.difference (symOf tar) $ symOf src ]
555        else
556          [ text "by totalizing"
557          , pretty $ Set.map (uncurry idToOpSymbol) $ Map.keysSet ops ]]
558    else fsep
559      [ pretty (morphismToSymbMapAux True mor)
560          $+$ fM (extended_map mor)
561      , colon <+> srcD, mapsto <+> prSig tar ]
562
563instance (Pretty e, Pretty f, Pretty m) =>
564    Pretty (Morphism f e m) where
565       pretty = printMorphism pretty pretty pretty
Note: See TracBrowser for help on using the browser.