| 1 | {- | |
|---|
| 2 | Module : $Header$ |
|---|
| 3 | Description : Abstract syntax of CASL basic specifications |
|---|
| 4 | Copyright : (c) Klaus Luettich, Christian Maeder, Uni Bremen 2002-2006 |
|---|
| 5 | License : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt |
|---|
| 6 | |
|---|
| 7 | Maintainer : Christian.Maeder@dfki.de |
|---|
| 8 | Stability : provisional |
|---|
| 9 | Portability : portable |
|---|
| 10 | |
|---|
| 11 | Abstract Syntax of CASL Basic_specs, Symb_items and Symb_map_items. |
|---|
| 12 | |
|---|
| 13 | Follows Sect. II:2.2 of the CASL Reference Manual. |
|---|
| 14 | -} |
|---|
| 15 | |
|---|
| 16 | module CASL.AS_Basic_CASL where |
|---|
| 17 | |
|---|
| 18 | import Common.Id |
|---|
| 19 | import Common.AS_Annotation |
|---|
| 20 | import qualified Data.Set as Set |
|---|
| 21 | |
|---|
| 22 | -- DrIFT command |
|---|
| 23 | {-! global: GetRange !-} |
|---|
| 24 | |
|---|
| 25 | data BASIC_SPEC b s f = Basic_spec [Annoted (BASIC_ITEMS b s f)] |
|---|
| 26 | deriving Show |
|---|
| 27 | |
|---|
| 28 | data BASIC_ITEMS b s f = Sig_items (SIG_ITEMS s f) |
|---|
| 29 | -- the Annotation following the keyword is dropped |
|---|
| 30 | -- but preceding the keyword is now an Annotation allowed |
|---|
| 31 | | Free_datatype SortsKind [Annoted DATATYPE_DECL] Range |
|---|
| 32 | -- pos: free, type, semi colons |
|---|
| 33 | | Sort_gen [Annoted (SIG_ITEMS s f)] Range |
|---|
| 34 | -- pos: generated, opt. braces |
|---|
| 35 | | Var_items [VAR_DECL] Range |
|---|
| 36 | -- pos: var, semi colons |
|---|
| 37 | | Local_var_axioms [VAR_DECL] [Annoted (FORMULA f)] Range |
|---|
| 38 | -- pos: forall, semi colons, dots |
|---|
| 39 | | Axiom_items [Annoted (FORMULA f)] Range |
|---|
| 40 | -- pos: dots |
|---|
| 41 | | Ext_BASIC_ITEMS b |
|---|
| 42 | deriving Show |
|---|
| 43 | |
|---|
| 44 | data SortsKind = NonEmptySorts | PossiblyEmptySorts deriving Show |
|---|
| 45 | |
|---|
| 46 | data SIG_ITEMS s f = Sort_items SortsKind [Annoted (SORT_ITEM f)] Range |
|---|
| 47 | -- pos: sort, semi colons |
|---|
| 48 | | Op_items [Annoted (OP_ITEM f)] Range |
|---|
| 49 | -- pos: op, semi colons |
|---|
| 50 | | Pred_items [Annoted (PRED_ITEM f)] Range |
|---|
| 51 | -- pos: pred, semi colons |
|---|
| 52 | | Datatype_items SortsKind [Annoted DATATYPE_DECL] Range |
|---|
| 53 | -- type, semi colons |
|---|
| 54 | | Ext_SIG_ITEMS s |
|---|
| 55 | deriving Show |
|---|
| 56 | |
|---|
| 57 | data SORT_ITEM f = Sort_decl [SORT] Range |
|---|
| 58 | -- pos: commas |
|---|
| 59 | | Subsort_decl [SORT] SORT Range |
|---|
| 60 | -- pos: commas, < |
|---|
| 61 | | Subsort_defn SORT VAR SORT (Annoted (FORMULA f)) Range |
|---|
| 62 | -- pos: "=", "{", ":", ".", "}" |
|---|
| 63 | -- the left anno list stored in Annoted Formula is |
|---|
| 64 | -- parsed after the equal sign |
|---|
| 65 | | Iso_decl [SORT] Range |
|---|
| 66 | -- pos: "="s |
|---|
| 67 | deriving Show |
|---|
| 68 | |
|---|
| 69 | data OP_ITEM f = Op_decl [OP_NAME] OP_TYPE [OP_ATTR f] Range |
|---|
| 70 | -- pos: commas, colon, OP_ATTR sep. by commas |
|---|
| 71 | | Op_defn OP_NAME OP_HEAD (Annoted (TERM f)) Range |
|---|
| 72 | -- pos: "=" |
|---|
| 73 | deriving Show |
|---|
| 74 | |
|---|
| 75 | data OpKind = Total | Partial deriving (Show, Eq, Ord) |
|---|
| 76 | |
|---|
| 77 | data OP_TYPE = Op_type OpKind [SORT] SORT Range |
|---|
| 78 | -- pos: "*"s, "->" ; if null [SORT] then Range = [] or pos: "?" |
|---|
| 79 | deriving (Show, Eq, Ord) |
|---|
| 80 | |
|---|
| 81 | args_OP_TYPE :: OP_TYPE -> [SORT] |
|---|
| 82 | args_OP_TYPE (Op_type _ args _ _) = args |
|---|
| 83 | |
|---|
| 84 | res_OP_TYPE :: OP_TYPE -> SORT |
|---|
| 85 | res_OP_TYPE (Op_type _ _ res _) = res |
|---|
| 86 | |
|---|
| 87 | data OP_HEAD = Op_head OpKind [ARG_DECL] SORT Range |
|---|
| 88 | -- pos: "(", semicolons, ")", colon |
|---|
| 89 | deriving Show |
|---|
| 90 | |
|---|
| 91 | data ARG_DECL = Arg_decl [VAR] SORT Range |
|---|
| 92 | -- pos: commas, colon |
|---|
| 93 | deriving Show |
|---|
| 94 | |
|---|
| 95 | data OP_ATTR f = Assoc_op_attr | Comm_op_attr | Idem_op_attr |
|---|
| 96 | | Unit_op_attr (TERM f) |
|---|
| 97 | deriving (Show, Eq, Ord) |
|---|
| 98 | |
|---|
| 99 | data PRED_ITEM f = Pred_decl [PRED_NAME] PRED_TYPE Range |
|---|
| 100 | -- pos: commas, colon |
|---|
| 101 | | Pred_defn PRED_NAME PRED_HEAD (Annoted (FORMULA f)) Range |
|---|
| 102 | -- pos: "<=>" |
|---|
| 103 | deriving Show |
|---|
| 104 | |
|---|
| 105 | data PRED_TYPE = Pred_type [SORT] Range |
|---|
| 106 | -- pos: if null [SORT] then "(",")" else "*"s |
|---|
| 107 | deriving (Show, Eq, Ord) |
|---|
| 108 | |
|---|
| 109 | data PRED_HEAD = Pred_head [ARG_DECL] Range |
|---|
| 110 | -- pos: "(",semi colons , ")" |
|---|
| 111 | deriving Show |
|---|
| 112 | |
|---|
| 113 | data DATATYPE_DECL = Datatype_decl SORT [Annoted ALTERNATIVE] Range |
|---|
| 114 | -- pos: "::=", "|"s |
|---|
| 115 | deriving Show |
|---|
| 116 | |
|---|
| 117 | data ALTERNATIVE = Alt_construct OpKind OP_NAME [COMPONENTS] Range |
|---|
| 118 | -- pos: "(", semi colons, ")" optional "?" |
|---|
| 119 | | Subsorts [SORT] Range |
|---|
| 120 | -- pos: sort, commas |
|---|
| 121 | deriving Show |
|---|
| 122 | |
|---|
| 123 | data COMPONENTS = Cons_select OpKind [OP_NAME] SORT Range |
|---|
| 124 | -- pos: commas, colon or ":?" |
|---|
| 125 | | Sort SORT |
|---|
| 126 | deriving Show |
|---|
| 127 | |
|---|
| 128 | data VAR_DECL = Var_decl [VAR] SORT Range |
|---|
| 129 | -- pos: commas, colon |
|---|
| 130 | deriving (Show, Eq, Ord) |
|---|
| 131 | |
|---|
| 132 | {- Position definition for FORMULA: |
|---|
| 133 | Information on parens are also encoded in Range. If there |
|---|
| 134 | are more Pos than necessary there is a pair of Pos enclosing the |
|---|
| 135 | other Pos informations which encode the brackets of every kind |
|---|
| 136 | -} |
|---|
| 137 | |
|---|
| 138 | data FORMULA f = Quantification QUANTIFIER [VAR_DECL] (FORMULA f) Range |
|---|
| 139 | -- pos: QUANTIFIER, semi colons, dot |
|---|
| 140 | | Conjunction [FORMULA f] Range |
|---|
| 141 | -- pos: "/\"s |
|---|
| 142 | | Disjunction [FORMULA f] Range |
|---|
| 143 | -- pos: "\/"s |
|---|
| 144 | | Implication (FORMULA f) (FORMULA f) Bool Range |
|---|
| 145 | -- pos: "=>" or "if" (True -> "=>") |
|---|
| 146 | | Equivalence (FORMULA f) (FORMULA f) Range |
|---|
| 147 | -- pos: "<=>" |
|---|
| 148 | | Negation (FORMULA f) Range |
|---|
| 149 | -- pos: not |
|---|
| 150 | | True_atom Range |
|---|
| 151 | -- pos: true |
|---|
| 152 | | False_atom Range |
|---|
| 153 | -- pos: false |
|---|
| 154 | | Predication PRED_SYMB [TERM f] Range |
|---|
| 155 | -- pos: opt. "(",commas,")" |
|---|
| 156 | | Definedness (TERM f) Range |
|---|
| 157 | -- pos: def |
|---|
| 158 | | Existl_equation (TERM f) (TERM f) Range |
|---|
| 159 | -- pos: =e= |
|---|
| 160 | | Strong_equation (TERM f) (TERM f) Range |
|---|
| 161 | -- pos: = |
|---|
| 162 | | Membership (TERM f) SORT Range |
|---|
| 163 | -- pos: in |
|---|
| 164 | | Mixfix_formula (TERM f) -- Mixfix_ Term/Token/(..)/[..]/{..} |
|---|
| 165 | -- a formula left original for mixfix analysis |
|---|
| 166 | | Unparsed_formula String Range |
|---|
| 167 | -- pos: first Char in String |
|---|
| 168 | | Sort_gen_ax [Constraint] Bool -- flag: belongs to a free type? |
|---|
| 169 | | ExtFORMULA f |
|---|
| 170 | -- needed for CASL extensions |
|---|
| 171 | deriving (Show, Eq, Ord) |
|---|
| 172 | |
|---|
| 173 | is_True_atom, is_False_atom :: FORMULA f -> Bool |
|---|
| 174 | is_True_atom (True_atom _) = True |
|---|
| 175 | is_True_atom _ = False |
|---|
| 176 | is_False_atom (False_atom _) = True |
|---|
| 177 | is_False_atom _ = False |
|---|
| 178 | |
|---|
| 179 | {- In the CASL institution, sort generation constraints have an |
|---|
| 180 | additional signature morphism component (Sect. III:2.1.3, p.134 of the |
|---|
| 181 | CASL Reference Manual). The extra signature morphism component is |
|---|
| 182 | needed because the naive translation of sort generation constraints |
|---|
| 183 | along signature morphisms may violate the satisfaction condition, |
|---|
| 184 | namely when sorts are identified by the translation, with the effect |
|---|
| 185 | that new terms can be formed. We avoid this extra component here and |
|---|
| 186 | instead use natural numbers to decorate sorts, in this way retaining |
|---|
| 187 | their identity w.r.t. the original signature. The newSort in a |
|---|
| 188 | Constraint is implicitly decorated with its index in the list of |
|---|
| 189 | Constraints. The opSymbs component collects all the operation symbols |
|---|
| 190 | with newSort (with that index!) as a result sort. The argument sorts |
|---|
| 191 | of an operation symbol are decorated explicitly via a list [Int] of |
|---|
| 192 | integers. The origSort in a Constraint is the original sort |
|---|
| 193 | corresponding to the index. A negative index indicates a sort outside |
|---|
| 194 | the constraint (i.e. a "parameter sort"). Note that this representation of |
|---|
| 195 | sort generation constraints is efficiently tailored towards both the use in |
|---|
| 196 | the proof calculus (Chap. IV:2, p. 282 of the CASL Reference Manual) |
|---|
| 197 | and the coding into second order logic (p. 429 of Theoret. Comp. Sci. 286). |
|---|
| 198 | -} |
|---|
| 199 | |
|---|
| 200 | data Constraint = Constraint { newSort :: SORT, |
|---|
| 201 | opSymbs :: [(OP_SYMB,[Int])], |
|---|
| 202 | origSort :: SORT } |
|---|
| 203 | deriving (Show, Eq, Ord) |
|---|
| 204 | |
|---|
| 205 | isInjectiveList :: Ord a => [a] -> Bool |
|---|
| 206 | isInjectiveList l = Set.size (Set.fromList l) == length l |
|---|
| 207 | |
|---|
| 208 | -- | from a Sort_gex_ax, recover: |
|---|
| 209 | -- | a traditional sort generation constraint plus a sort mapping |
|---|
| 210 | recover_Sort_gen_ax :: [Constraint] -> |
|---|
| 211 | ([SORT],[OP_SYMB],[(SORT,SORT)]) |
|---|
| 212 | recover_Sort_gen_ax constrs = |
|---|
| 213 | if isInjectiveList sorts |
|---|
| 214 | -- no duplicate sorts, i.e. injective sort map? Then we can ignore indices |
|---|
| 215 | then (sorts,map fst (concat (map opSymbs constrs)),[]) |
|---|
| 216 | -- otherwise, we have to introduce new sorts for the indices |
|---|
| 217 | -- and afterwards rename them into the sorts they denote |
|---|
| 218 | else (map indSort1 indices,map indOp indOps1,map sortMap indSorts) |
|---|
| 219 | where |
|---|
| 220 | sorts = map newSort constrs |
|---|
| 221 | indices = [0..length sorts-1] |
|---|
| 222 | indSorts = zip indices sorts |
|---|
| 223 | indSort (i,s) = if i<0 then s else indSort1 i |
|---|
| 224 | indSort1 i = origSort $ head (drop i constrs) |
|---|
| 225 | sortMap (i,s) = (indSort1 i,s) |
|---|
| 226 | indOps = zip indices (map opSymbs constrs) |
|---|
| 227 | indOps1 = concat (map (\(i,ops) -> map ((,) i) ops) indOps) |
|---|
| 228 | indOp (res,(Qual_op_name on (Op_type k args1 res1 pos1) pos,args)) = |
|---|
| 229 | Qual_op_name on |
|---|
| 230 | (Op_type k (map indSort (zip args args1)) |
|---|
| 231 | (indSort (res,res1)) pos1) pos |
|---|
| 232 | indOp _ = error |
|---|
| 233 | "CASL/AS_Basic_CASL: Internal error: Unqualified OP_SYMB in Sort_gen_ax" |
|---|
| 234 | |
|---|
| 235 | -- | from a free Sort_gex_ax, recover: |
|---|
| 236 | -- | the sorts, each paired with the constructors |
|---|
| 237 | -- | fails (i.e. delivers Nothing) if the sort map is not injective |
|---|
| 238 | recover_free_Sort_gen_ax :: [Constraint] -> Maybe [(SORT,[OP_SYMB])] |
|---|
| 239 | recover_free_Sort_gen_ax constrs = |
|---|
| 240 | if isInjectiveList sorts |
|---|
| 241 | -- no duplicate sorts, i.e. injective sort map? |
|---|
| 242 | then Just $ map getOpProfile constrs |
|---|
| 243 | else Nothing |
|---|
| 244 | where |
|---|
| 245 | sorts = map newSort constrs |
|---|
| 246 | getOpProfile constr = (newSort constr, map fst $ opSymbs constr) |
|---|
| 247 | |
|---|
| 248 | data QUANTIFIER = Universal | Existential | Unique_existential |
|---|
| 249 | deriving (Show, Eq, Ord) |
|---|
| 250 | |
|---|
| 251 | data PRED_SYMB = Pred_name PRED_NAME |
|---|
| 252 | | Qual_pred_name PRED_NAME PRED_TYPE Range |
|---|
| 253 | -- pos: "(", pred, colon, ")" |
|---|
| 254 | deriving (Show, Eq, Ord) |
|---|
| 255 | |
|---|
| 256 | predSymbName :: PRED_SYMB -> PRED_NAME |
|---|
| 257 | predSymbName p = case p of |
|---|
| 258 | Pred_name n -> n |
|---|
| 259 | Qual_pred_name n _ _ -> n |
|---|
| 260 | |
|---|
| 261 | data TERM f = Qual_var VAR SORT Range -- pos: "(", var, colon, ")" |
|---|
| 262 | | Application OP_SYMB [TERM f] Range |
|---|
| 263 | -- pos: parens around TERM f if any and seperating commas |
|---|
| 264 | | Sorted_term (TERM f) SORT Range |
|---|
| 265 | -- pos: colon |
|---|
| 266 | | Cast (TERM f) SORT Range |
|---|
| 267 | -- pos: "as" |
|---|
| 268 | | Conditional (TERM f) (FORMULA f) (TERM f) Range |
|---|
| 269 | -- pos: "when", "else" |
|---|
| 270 | | Unparsed_term String Range -- SML-CATS |
|---|
| 271 | |
|---|
| 272 | -- A new intermediate state |
|---|
| 273 | | Mixfix_qual_pred PRED_SYMB -- as part of a mixfix formula |
|---|
| 274 | | Mixfix_term [TERM f] -- not starting with Mixfix_sorted_term/cast |
|---|
| 275 | | Mixfix_token Token -- NO-BRACKET-TOKEN, LITERAL, PLACE |
|---|
| 276 | | Mixfix_sorted_term SORT Range |
|---|
| 277 | -- pos: colon |
|---|
| 278 | | Mixfix_cast SORT Range |
|---|
| 279 | -- pos: "as" |
|---|
| 280 | | Mixfix_parenthesized [TERM f] Range -- non-emtpy term list |
|---|
| 281 | -- pos: "(", commas, ")" |
|---|
| 282 | | Mixfix_bracketed [TERM f] Range |
|---|
| 283 | -- pos: "[", commas, "]" |
|---|
| 284 | | Mixfix_braced [TERM f] Range -- also for list-notation |
|---|
| 285 | -- pos: "{", "}" |
|---|
| 286 | deriving (Show, Eq, Ord) |
|---|
| 287 | |
|---|
| 288 | -- | state after mixfix- but before overload resolution |
|---|
| 289 | varOrConst :: Token -> TERM f |
|---|
| 290 | varOrConst t = Application (Op_name $ simpleIdToId t) [] $ tokPos t |
|---|
| 291 | |
|---|
| 292 | rangeOfTerm :: TERM f -> Range |
|---|
| 293 | rangeOfTerm t = case t of |
|---|
| 294 | Mixfix_term ts -> concatMapRange rangeOfTerm ts |
|---|
| 295 | Mixfix_token s -> tokPos s |
|---|
| 296 | _ -> getRange t |
|---|
| 297 | |
|---|
| 298 | data OP_SYMB = Op_name OP_NAME |
|---|
| 299 | | Qual_op_name OP_NAME OP_TYPE Range |
|---|
| 300 | -- pos: "(", op, colon, ")" |
|---|
| 301 | deriving (Show, Eq, Ord) |
|---|
| 302 | |
|---|
| 303 | opSymbName :: OP_SYMB -> OP_NAME |
|---|
| 304 | opSymbName o = case o of |
|---|
| 305 | Op_name n -> n |
|---|
| 306 | Qual_op_name n _ _ -> n |
|---|
| 307 | |
|---|
| 308 | type CASLFORMULA = FORMULA () |
|---|
| 309 | type CASLTERM = TERM () |
|---|
| 310 | |
|---|
| 311 | type OP_NAME = Id |
|---|
| 312 | type PRED_NAME = Id |
|---|
| 313 | type SORT = Id |
|---|
| 314 | type VAR = Token |
|---|
| 315 | |
|---|
| 316 | data SYMB_ITEMS = Symb_items SYMB_KIND [SYMB] Range |
|---|
| 317 | -- pos: SYMB_KIND, commas |
|---|
| 318 | deriving (Show, Eq) |
|---|
| 319 | |
|---|
| 320 | data SYMB_MAP_ITEMS = Symb_map_items SYMB_KIND [SYMB_OR_MAP] Range |
|---|
| 321 | -- pos: SYMB_KIND, commas |
|---|
| 322 | deriving (Show, Eq) |
|---|
| 323 | |
|---|
| 324 | data SYMB_KIND = Implicit | Sorts_kind |
|---|
| 325 | | Ops_kind | Preds_kind | OtherKinds String |
|---|
| 326 | deriving (Show, Eq, Ord) |
|---|
| 327 | |
|---|
| 328 | data SYMB = Symb_id Id |
|---|
| 329 | | Qual_id Id TYPE Range |
|---|
| 330 | -- pos: colon |
|---|
| 331 | deriving (Show, Eq) |
|---|
| 332 | |
|---|
| 333 | data TYPE = O_type OP_TYPE |
|---|
| 334 | | P_type PRED_TYPE |
|---|
| 335 | | A_type SORT -- ambiguous pred or (constant total) op |
|---|
| 336 | deriving (Show, Eq) |
|---|
| 337 | |
|---|
| 338 | data SYMB_OR_MAP = Symb SYMB |
|---|
| 339 | | Symb_map SYMB SYMB Range |
|---|
| 340 | -- pos: "|->" |
|---|
| 341 | deriving (Show, Eq) |
|---|