-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathSign.hs
604 lines (492 loc) · 20.2 KB
/
Sign.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
{-# LANGUAGE DeriveDataTypeable #-}
{- |
Module : ./CASL/Sign.hs
Description : CASL signatures and local environments for basic analysis
Copyright : (c) Christian Maeder and Uni Bremen 2002-2006
License : GPLv2 or higher, see LICENSE.txt
Maintainer : [email protected]
Stability : provisional
Portability : portable
CASL signatures also serve as local environments for the basic static analysis
-}
module CASL.Sign where
import CASL.AS_Basic_CASL
import CASL.Fold
import CASL.ToDoc ()
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Common.Lib.MapSet as MapSet
import qualified Common.Lib.Rel as Rel
import qualified Common.Lib.State as State
import Common.Keywords
import Common.Id
import Common.Result
import Common.AS_Annotation
import Common.GlobalAnnotations
import Common.Prec (mkPrecIntMap, PrecMap)
import Common.Doc
import Common.DocUtils
import Data.Data
import Data.Maybe (fromMaybe)
import Data.List (isPrefixOf)
import Control.Monad (when, unless)
-- constants have empty argument lists
data OpType = OpType {opKind :: OpKind, opArgs :: [SORT], opRes :: SORT}
deriving (Show, Eq, Ord, Typeable, Data)
-- | result sort added to argument sorts
opSorts :: OpType -> [SORT]
opSorts o = opRes o : opArgs o
mkTotOpType :: [SORT] -> SORT -> OpType
mkTotOpType = OpType Total
sortToOpType :: SORT -> OpType
sortToOpType = mkTotOpType []
isSingleArgOp :: OpType -> Bool
isSingleArgOp = isSingle . opArgs
data PredType = PredType {predArgs :: [SORT]} deriving (Show, Eq, Ord, Typeable, Data)
sortToPredType :: SORT -> PredType
sortToPredType s = PredType [s]
isBinPredType :: PredType -> Bool
isBinPredType (PredType l) = case l of
[_, _] -> True
_ -> False
type OpMap = MapSet.MapSet OP_NAME OpType
type PredMap = MapSet.MapSet PRED_NAME PredType
type AnnoMap = MapSet.MapSet Symbol Annotation
data SymbType = SortAsItemType
| SubsortAsItemType SORT -- special symbols for xml output
| OpAsItemType OpType
{- since symbols do not speak about totality, the totality
information in OpType has to be ignored -}
| PredAsItemType PredType
deriving (Show, Eq, Ord, Typeable, Data)
symbolKind :: SymbType -> SYMB_KIND
symbolKind t = case t of
OpAsItemType _ -> Ops_kind
PredAsItemType _ -> Preds_kind
_ -> Sorts_kind
data Symbol = Symbol {symName :: Id, symbType :: SymbType}
deriving (Show, Eq, Ord, Typeable, Data)
instance GetRange Symbol where
getRange = getRange . symName
rangeSpan = rangeSpan . symName
idToSortSymbol :: Id -> Symbol
idToSortSymbol idt = Symbol idt SortAsItemType
idToOpSymbol :: Id -> OpType -> Symbol
idToOpSymbol idt = Symbol idt . OpAsItemType
idToPredSymbol :: Id -> PredType -> Symbol
idToPredSymbol idt = Symbol idt . PredAsItemType
type CASLSign = Sign () ()
{- | the data type for the basic static analysis to accumulate variables,
sentences, symbols, diagnostics and annotations, that are removed or ignored
when looking at signatures from outside, i.e. during logic-independent
processing. -}
data Sign f e = Sign
{ sortRel :: Rel.Rel SORT
-- ^ every sort is a subsort of itself
, revSortRel :: Maybe (Rel.Rel SORT)
-- ^ reverse sort relation for more efficient lookup of subsorts
, emptySortSet :: Set.Set SORT
-- ^ a subset of the sort set of possibly empty sorts
, opMap :: OpMap
, assocOps :: OpMap -- ^ the subset of associative operators
, predMap :: PredMap
, varMap :: Map.Map SIMPLE_ID SORT -- ^ temporary variables
, sentences :: [Named (FORMULA f)] -- ^ current sentences
, declaredSymbols :: Set.Set Symbol -- ^ introduced or redeclared symbols
, envDiags :: [Diagnosis] -- ^ diagnostics for basic spec
, annoMap :: AnnoMap -- ^ annotated symbols
, globAnnos :: GlobalAnnos -- ^ global annotations to use
, extendedInfo :: e
} deriving (Show, Typeable, Data)
sortSet :: Sign f e -> Set.Set SORT
sortSet = Rel.keysSet . sortRel
-- better ignore assoc flags for equality
instance Eq e => Eq (Sign f e) where
a == b = compare a {extendedInfo = ()} b {extendedInfo = ()} == EQ
&& extendedInfo a == extendedInfo b
instance Ord e => Ord (Sign f e) where
compare a b = compare
(emptySortSet a, sortRel a, opMap a, predMap a, extendedInfo a)
(emptySortSet b, sortRel b, opMap b, predMap b, extendedInfo b)
emptySign :: e -> Sign f e
emptySign e = Sign
{ sortRel = Rel.empty
, revSortRel = Nothing
, emptySortSet = Set.empty
, opMap = MapSet.empty
, assocOps = MapSet.empty
, predMap = MapSet.empty
, varMap = Map.empty
, sentences = []
, declaredSymbols = Set.empty
, envDiags = []
, annoMap = MapSet.empty
, globAnnos = emptyGlobalAnnos
, extendedInfo = e }
embedSign :: e -> Sign f1 e1 -> Sign f e
embedSign e sign = (emptySign e)
{ sortRel = sortRel sign
, opMap = opMap sign
, assocOps = assocOps sign
, predMap = predMap sign }
mapForm :: f -> FORMULA f1 -> FORMULA f
mapForm c = foldFormula $ mapRecord (const c)
mapFORMULA :: FORMULA f1 -> FORMULA f
mapFORMULA = mapForm $ error "CASL.mapFORMULA"
embedTheory :: (FORMULA f1 -> FORMULA f) -> e
-> (Sign f1 e1, [Named (FORMULA f1)])
-> (Sign f e, [Named (FORMULA f)])
embedTheory f e (sign, sens) =
(embedSign e sign, map (mapNamed f) sens)
embedCASLTheory :: e -> (Sign f1 e1, [Named (FORMULA f1)])
-> (Sign f e, [Named (FORMULA f)])
embedCASLTheory = embedTheory mapFORMULA
getSyntaxTable :: Sign f e -> (PrecMap, AssocMap)
getSyntaxTable sig = let gannos = globAnnos sig
in (mkPrecIntMap $ prec_annos gannos, assoc_annos gannos)
class SignExtension e where
isSubSignExtension :: e -> e -> Bool
instance SignExtension () where
isSubSignExtension _ _ = True
-- | proper subsorts (possibly excluding input sort)
subsortsOf :: SORT -> Sign f e -> Set.Set SORT
subsortsOf s e = case revSortRel e of
Nothing -> Rel.predecessors (sortRel e) s
Just r -> Rel.succs r s
setRevSortRel :: Sign f e -> Sign f e
setRevSortRel s = s { revSortRel = Just . Rel.transpose $ sortRel s }
-- | proper supersorts (possibly excluding input sort)
supersortsOf :: SORT -> Sign f e -> Set.Set SORT
supersortsOf s e = Rel.succs (sortRel e) s
toOP_TYPE :: OpType -> OP_TYPE
toOP_TYPE OpType { opArgs = args, opRes = res, opKind = k } =
Op_type k args res nullRange
toPRED_TYPE :: PredType -> PRED_TYPE
toPRED_TYPE PredType { predArgs = args } = Pred_type args nullRange
toOpType :: OP_TYPE -> OpType
toOpType (Op_type k args r _) = OpType k args r
toPredType :: PRED_TYPE -> PredType
toPredType (Pred_type args _) = PredType args
instance Pretty OpType where
pretty = pretty . toOP_TYPE
instance Pretty PredType where
pretty = pretty . toPRED_TYPE
instance (Show f, Pretty e) => Pretty (Sign f e) where
pretty = printSign pretty
instance Pretty Symbol where
pretty sy = let n = pretty (symName sy) in
case symbType sy of
SortAsItemType -> keyword sortS <+> n
SubsortAsItemType s -> keyword sortS <+> n <+> less <+> pretty s
PredAsItemType pt -> keyword predS <+> n <+> colon <+> pretty pt
OpAsItemType ot -> keyword opS <+> n <+> colon <> pretty ot
eqAndSubsorts :: Bool -> Rel.Rel SORT -> ([[SORT]], [(SORT, [SORT])])
eqAndSubsorts groupSubsorts srel = let
cs = Rel.sccOfClosure srel
in ( filter ((> 1) . length) $ map Set.toList cs
, Map.toList . Map.map Set.toList . Rel.toMap . Rel.rmNullSets
. (if groupSubsorts then Rel.transpose else id)
. Rel.transReduce . Rel.irreflex $ Rel.collaps cs srel)
singleAndRelatedSorts :: Rel.Rel SORT -> ([SORT], [[SORT]])
singleAndRelatedSorts srel = let
ss = Rel.keysSet srel
rs = Rel.sccOfClosure
. Rel.transClosure . Rel.union srel $ Rel.transpose srel
is = Set.difference ss $ Set.unions rs
in (Set.toList is, map Set.toList rs)
printSign :: (e -> Doc) -> Sign f e -> Doc
printSign fE s = let
printRel (supersort, subsorts) =
ppWithCommas subsorts <+> text lessS <+>
idDoc supersort
esorts = emptySortSet s
srel = sortRel s
(es, ss) = eqAndSubsorts True srel
nsorts = Set.difference (sortSet s) esorts in
(if Set.null nsorts then empty else text (sortS ++ sS) <+>
sepByCommas (map idDoc (Set.toList nsorts))) $+$
(if Set.null esorts then empty else text (esortS ++ sS) <+>
sepByCommas (map idDoc (Set.toList esorts))) $+$
(if Rel.noPairs srel then empty
else text (sortS ++ sS) <+>
fsep (punctuate semi $
map (fsep . punctuate (space <> equals) . map pretty) es
++ map printRel ss))
$+$ printSetMap (text opS) empty (MapSet.toMap $ opMap s)
$+$ printSetMap (text predS) space (MapSet.toMap $ predMap s)
$+$ fE (extendedInfo s)
-- working with Sign
closeSortRel :: Sign f e -> Sign f e
closeSortRel s =
s { sortRel = Rel.transClosure $ sortRel s }
nonEmptySortSet :: Sign f e -> Set.Set Id
nonEmptySortSet s = Set.difference (sortSet s) $ emptySortSet s
-- op kinds of op types
setOpKind :: OpKind -> OpType -> OpType
setOpKind k o = o { opKind = k }
mkPartial :: OpType -> OpType
mkPartial = setOpKind Partial
mkTotal :: OpType -> OpType
mkTotal = setOpKind Total
isTotal :: OpType -> Bool
isTotal = (== Total) . opKind
isPartial :: OpType -> Bool
isPartial = not . isTotal
makePartial :: Set.Set OpType -> Set.Set OpType
makePartial = Set.mapMonotonic mkPartial
-- | remove (True) or add (False) partial op if it is included as total
rmOrAddParts :: Bool -> Set.Set OpType -> Set.Set OpType
rmOrAddParts b s =
let t = makePartial $ Set.filter isTotal s
in (if b then Set.difference else Set.union) s t
rmOrAddPartsMap :: Bool -> OpMap -> OpMap
rmOrAddPartsMap b = MapSet.mapSet (rmOrAddParts b)
diffMapSet :: PredMap -> PredMap -> PredMap
diffMapSet = MapSet.difference
diffOpMapSet :: OpMap -> OpMap -> OpMap
diffOpMapSet m = MapSet.difference m . rmOrAddPartsMap False
diffSig :: (e -> e -> e) -> Sign f e -> Sign f e -> Sign f e
diffSig dif a b = let s = sortSet a `Set.difference` sortSet b in
closeSortRel a
{ emptySortSet = Set.difference s
$ nonEmptySortSet a `Set.difference` nonEmptySortSet b
, sortRel = Rel.difference (Rel.transReduce $ sortRel a)
. Rel.transReduce $ sortRel b
, opMap = opMap a `diffOpMapSet` opMap b
, assocOps = assocOps a `diffOpMapSet` assocOps b
, predMap = predMap a `diffMapSet` predMap b
, annoMap = annoMap a `MapSet.difference` annoMap b
, extendedInfo = dif (extendedInfo a) $ extendedInfo b }
{- transClosure needed: {a < b < c} - {a < c; b}
is not transitive! -}
addOpMapSet :: OpMap -> OpMap -> OpMap
addOpMapSet m = rmOrAddPartsMap True . MapSet.union m
addMapSet :: PredMap -> PredMap -> PredMap
addMapSet = MapSet.union
addSig :: (e -> e -> e) -> Sign f e -> Sign f e -> Sign f e
addSig ad a b = let s = sortSet a `Set.union` sortSet b in
closeSortRel a
{ emptySortSet = Set.difference s
$ nonEmptySortSet a `Set.union` nonEmptySortSet b
, sortRel = Rel.union (sortRel a) $ sortRel b
, opMap = addOpMapSet (opMap a) $ opMap b
, assocOps = addOpMapSet (assocOps a) $ assocOps b
, predMap = MapSet.union (predMap a) $ predMap b
, annoMap = MapSet.union (annoMap a) $ annoMap b
, extendedInfo = ad (extendedInfo a) $ extendedInfo b }
uniteCASLSign :: CASLSign -> CASLSign -> CASLSign
uniteCASLSign = addSig (\ _ _ -> ())
interRel :: (Show a, Ord a) => Rel.Rel a -> Rel.Rel a -> Rel.Rel a
interRel a =
Rel.fromSet
. Set.intersection (Rel.toSet a) . Rel.toSet
interOpMapSet :: OpMap -> OpMap -> OpMap
interOpMapSet m = rmOrAddPartsMap True
. MapSet.intersection (rmOrAddPartsMap False m) . rmOrAddPartsMap False
interMapSet :: PredMap -> PredMap -> PredMap
interMapSet = MapSet.intersection
interSig :: (e -> e -> e) -> Sign f e -> Sign f e -> Sign f e
interSig ef a b = let s = sortSet a `Set.intersection` sortSet b in
closeSortRel a
{ emptySortSet = Set.difference s
$ nonEmptySortSet a `Set.intersection` nonEmptySortSet b
, sortRel = interRel (sortRel a) $ sortRel b
, opMap = interOpMapSet (opMap a) $ opMap b
, assocOps = interOpMapSet (assocOps a) $ assocOps b
, predMap = interMapSet (predMap a) $ predMap b
, annoMap = MapSet.intersection (annoMap a) $ annoMap b
, extendedInfo = ef (extendedInfo a) $ extendedInfo b }
isSubOpMap :: OpMap -> OpMap -> Bool
isSubOpMap m = Map.isSubmapOfBy (\ s t -> MapSet.setAll
(\ e -> Set.member e t || isPartial e && Set.member (mkTotal e) t)
s) (MapSet.toMap m) . MapSet.toMap
isSubMap :: PredMap -> PredMap -> Bool
isSubMap = MapSet.isSubmapOf
isSubSig :: (e -> e -> Bool) -> Sign f e -> Sign f e -> Bool
isSubSig isSubExt a b =
Rel.isSubrelOf (sortRel a) (sortRel b)
-- ignore empty sort sorts
&& isSubOpMap (opMap a) (opMap b)
-- ignore associativity properties!
&& isSubMap (predMap a) (predMap b)
&& isSubExt (extendedInfo a) (extendedInfo b)
mapSetToList :: MapSet.MapSet a b -> [(a, b)]
mapSetToList = MapSet.toPairList
addDiags :: [Diagnosis] -> State.State (Sign f e) ()
addDiags ds = do
e <- State.get
State.put e { envDiags = reverse ds ++ envDiags e }
addAnnoSet :: Annoted a -> Symbol -> State.State (Sign f e) ()
addAnnoSet a s = do
addSymbol s
let v = Set.union (Set.fromList $ l_annos a) $ Set.fromList $ r_annos a
unless (Set.null v) $ do
e <- State.get
State.put e { annoMap = MapSet.update (Set.union v) s $ annoMap e }
addSymbol :: Symbol -> State.State (Sign f e) ()
addSymbol s = do
e <- State.get
State.put $ addSymbToDeclSymbs e s
addSymbToDeclSymbs :: Sign e f -> Symbol -> Sign e f
addSymbToDeclSymbs cs sy =
cs { declaredSymbols = Set.insert sy $ declaredSymbols cs }
addSort :: SortsKind -> Annoted a -> SORT -> State.State (Sign f e) ()
addSort sk a s = do
e <- State.get
let r = sortRel e
em = emptySortSet e
known = Rel.memberKey s r
if known then addDiags [mkDiag Hint "redeclared sort" s]
else do
State.put e { sortRel = Rel.insertKey s r }
addDiags $ checkNamePrefix s
case sk of
NonEmptySorts -> when (Set.member s em) $ do
e2 <- State.get
State.put e2 { emptySortSet = Set.delete s em }
addDiags [mkDiag Warning "redeclared sort as non-empty" s]
PossiblyEmptySorts -> if known then
addDiags [mkDiag Warning "non-empty sort remains non-empty" s]
else do
e2 <- State.get
State.put e2 { emptySortSet = Set.insert s em }
addAnnoSet a $ Symbol s SortAsItemType
hasSort :: Sign f e -> SORT -> [Diagnosis]
hasSort e s =
[ mkDiag Error "unknown sort" s
| not $ Set.member s $ sortSet e ]
checkSorts :: [SORT] -> State.State (Sign f e) ()
checkSorts s = do
e <- State.get
addDiags $ concatMap (hasSort e) s
addSubsort :: SORT -> SORT -> State.State (Sign f e) ()
addSubsort = addSubsortOrIso True
addSubsortOrIso :: Bool -> SORT -> SORT -> State.State (Sign f e) ()
addSubsortOrIso b super sub = do
when b $ checkSorts [super, sub]
e <- State.get
let r = sortRel e
State.put e { sortRel = (if b then id else Rel.insertDiffPair super sub)
$ Rel.insertDiffPair sub super r }
let p = posOfId sub
rel = " '" ++
showDoc sub (if b then " < " else " = ") ++ showDoc super "'"
if super == sub then addDiags [mkDiag Warning "void reflexive subsort" sub]
else if b then
if Rel.path super sub r then
addDiags $ if Rel.path sub super r
then [Diag Warning ("sorts are isomorphic" ++ rel) p]
else [Diag Warning ("added subsort cycle by" ++ rel) p]
else when (Rel.path sub super r)
$ addDiags [Diag Hint ("redeclared subsort" ++ rel) p]
else if Rel.path super sub r then
addDiags $ if Rel.path sub super r
then [Diag Hint ("redeclared isomoprhic sorts" ++ rel) p]
else [Diag Warning ("subsort '" ++
showDoc super "' made isomorphic by" ++ rel) $ posOfId super]
else when (Rel.path sub super r)
$ addDiags [Diag Warning ("subsort '" ++
showDoc sub "' made isomorphic by" ++ rel) p]
closeSubsortRel :: State.State (Sign f e) ()
closeSubsortRel =
do e <- State.get
State.put e { sortRel = Rel.transClosure $ sortRel e }
checkNamePrefix :: Id -> [Diagnosis]
checkNamePrefix i =
[ mkDiag Warning "identifier may conflict with generated names" i
| isPrefixOf genNamePrefix $ showId i ""]
alsoWarning :: String -> String -> Id -> [Diagnosis]
alsoWarning new old i = let is = ' ' : showId i "'" in
[Diag Warning ("new '" ++ new ++ is ++ " is also known as '" ++ old ++ is)
$ posOfId i]
checkWithMap :: String -> String -> Map.Map Id a -> Id -> [Diagnosis]
checkWithMap s1 s2 m i = if Map.member i m then alsoWarning s1 s2 i else []
checkWithOtherMap :: String -> String -> MapSet.MapSet Id a -> Id -> [Diagnosis]
checkWithOtherMap s1 s2 = checkWithMap s1 s2 . MapSet.toMap
addVars :: VAR_DECL -> State.State (Sign f e) ()
addVars (Var_decl vs s _) = do
checkSorts [s]
mapM_ (addVar s) vs
addVar :: SORT -> SIMPLE_ID -> State.State (Sign f e) ()
addVar s v =
do e <- State.get
let m = varMap e
i = simpleIdToId v
ds = case Map.lookup v m of
Just _ -> [mkDiag Hint "known variable shadowed" v]
Nothing -> []
State.put e { varMap = Map.insert v s m }
addDiags $ ds ++ checkWithOtherMap varS opS (opMap e) i
++ checkWithOtherMap varS predS (predMap e) i
++ checkNamePrefix i
addOpTo :: Id -> OpType -> OpMap -> OpMap
addOpTo = MapSet.insert
type VarSet = Set.Set (VAR, SORT)
{- | extract the sort and free variables from an analysed term. The input
signature for free variables is (currently only) used for statements in the
VSE logic. The conversion for boolean terms to formulas is only used for FPL.
-}
class TermExtension f where
freeVarsOfExt :: Sign f e -> f -> VarSet
freeVarsOfExt _ = const Set.empty
optTermSort :: f -> Maybe SORT
optTermSort = const Nothing
sortOfTerm :: f -> SORT
sortOfTerm = fromMaybe (genName "unknown") . optTermSort
termToFormula :: TERM f -> Result (FORMULA f)
termToFormula = const $ Result [] Nothing
instance TermExtension ()
instance TermExtension f => TermExtension (TERM f) where
optTermSort = optSortOfTerm optTermSort
optSortOfTerm :: (f -> Maybe SORT) -> TERM f -> Maybe SORT
optSortOfTerm f term = case term of
Qual_var _ ty _ -> Just ty
Application (Qual_op_name _ ot _) _ _ -> Just $ res_OP_TYPE ot
Sorted_term _ ty _ -> Just ty
Cast _ ty _ -> Just ty
Conditional t1 _ _ _ -> optSortOfTerm f t1
ExtTERM t -> f t
_ -> Nothing
mkAxName :: String -> SORT -> SORT -> String
mkAxName str s s' = "ga_" ++ str ++ "_" ++ show s ++ "_to_" ++ show s'
mkAxNameSingle :: String -> SORT -> String
mkAxNameSingle str s = "ga_" ++ str ++ "_" ++ show s
mkSortGenName :: [SORT] -> String
mkSortGenName sl = "ga_generated_" ++ showSepList (showString "_") showId sl ""
{- | The sort generation constraint is given a generated name,
built from the sort list -}
toSortGenNamed :: FORMULA f -> [SORT] -> Named (FORMULA f)
toSortGenNamed f sl = makeNamed (mkSortGenName sl) f
getConstructors :: [Named (FORMULA f)] -> Set.Set (Id, OpType)
getConstructors = foldr (\ f s -> case sentence f of
Sort_gen_ax cs _ -> let
(_, ops, _) = recover_Sort_gen_ax cs
in foldr ( \ o -> case o of
Qual_op_name i t _ ->
Set.insert (i, mkPartial $ toOpType t)
_ -> id)
s ops
_ -> s) Set.empty
-- | adds a symbol to a given signature
addSymbToSign :: Sign e f -> Symbol -> Result (Sign e f)
addSymbToSign sig sy =
let addSort' cs s =
cs { sortRel = Rel.insertKey s $ sortRel cs }
addToMap' m n t = MapSet.insert n t m
addOp' cs n ot = cs { opMap = addToMap' (opMap cs) n ot }
addPred' cs n pt = cs { predMap = addToMap' (predMap cs) n pt }
in do
let sig' = addSymbToDeclSymbs sig sy
n = symName sy
case symbType sy of
SortAsItemType -> return $ addSort' sig' n
SubsortAsItemType _ -> return sig
PredAsItemType pt -> return $ addPred' sig' n pt
OpAsItemType ot -> return $ addOp' sig' n ot
-- The function below belong in a different file. But I put them here for now.
-- dual of a quantifier
dualQuant :: QUANTIFIER -> QUANTIFIER
dualQuant q = case q of
Universal -> Existential
Existential -> Universal
Unique_existential -> error "unique existential quantifier has no dual" -- should not get here