--> **************************************************************** --> parameterized list (generic list) --> **************************************************************** --> built-in module TRIV: trivial collection of elements show TRIV . --> TRIV is different from the user defined module TRIVu mod* TRIVu {[Elt]} --> because TRIVu has the built-in module BOOL as a sub-module show TRIVu . --> ---------------------------------------------------------------- --> parametrized list (i.e. generic list) --> ---------------------------------------------------------------- mod! LIST (X :: TRIV) { [List] op nil : -> List {constr} . op _|_ : Elt List -> List {constr} . } --> ---------------------------------------------------------------- --> PNAT: Peano NATural numbers --> ---------------------------------------------------------------- mod! PNAT { [Nat] op 0 : -> Nat {constr} . op s_ : Nat -> Nat {constr} . } -- instantiating 'X :: TRIV' to PNAT with a module expression -- 'open LIST(PNAT{sort Elt -> Nat}) .' -- sort map {sort Elt -> Nat} can be inferred and dropped open LIST(PNAT) . show . red nil = 0 | nil . red 0 | nil = s 0 | nil . red s 0 | nil = s 0 | nil . close #| -- outputs for the above open...close -- opening module LIST(X <= PNAT).. done. %LIST(X <= PNAT)> module LIST(X <= PNAT) { ** opening imports { protecting (PNAT) } signature { [ List ] op nil : -> List { constr prec: 0 } op _ | _ : Nat List -> List { constr prec: 41 } } } -- reduce in %LIST(X <= PNAT) : (nil = (0 | nil)):Bool (nil = (0 | nil)):Bool -- reduce in %LIST(X <= PNAT) : ((0 | nil) = ((s 0) | nil)):Bool ((0 | nil) = ((s 0) | nil)):Bool -- reduce in %LIST(X <= PNAT) : (((s 0) | nil) = ((s 0) | nil)):Bool (true):Bool |# --> ---------------------------------------------------------------- --> order-sorted PNATnz --> ---------------------------------------------------------------- mod! PNATnz { [NzNat < Nat] op 0 : -> Nat {constr} . op s_ : Nat -> NzNat {constr} . } -- 'open LIST(PNATnz) .' causes an error -- because there are two sorts NzNat and Nat, -- and {sort Elt -> Nat} is necessary open LIST(PNATnz{sort Elt -> Nat}) . show . red nil = 0 | nil . red 0 | nil = s 0 | nil . red s 0 | nil = s 0 | nil . close -- 'principal-sort Nat' is -- declared in the built-in module NAT -- hence the following works open LIST(NAT) . red nil = 0 | nil . red 0 | nil = 1 | nil . red 1 | nil = 1 | nil . close --> ---------------------------------------------------------------- --> parametrized list with 2 sorts parameter module TRIV2 --> ---------------------------------------------------------------- mod* TRIV2 principal-sort Elt { [EltSub < Elt] } mod! LIST2 (X2 :: TRIV2) { [List] op nil : -> List {constr} . op _|_ : Elt List -> List {constr} . } open LIST2(NAT{sort EltSub -> NzNat}) . show . red nil = 0 | nil . red 0 | nil = 1 | nil . red 1 | nil = 1 | nil . close -- if you want to give a name to the module LIST(PNAT) -- mod LISTofPNAT {pr(LIST(PNAT))} or make LISTofPNAT (LIST(PNAT)) open LISTofPNAT . show . red nil = 0 | nil . red 0 | nil = s 0 | nil . red s 0 | nil = s 0 | nil . close --> **************************************************************** --> Defining Equivalence over List --> **************************************************************** --> ---------------------------------------------------------------- --> trivial collection of elements with _=_ --> ---------------------------------------------------------------- mod* TRIV= { [Elt] op _=_ : Elt Elt -> Bool {comm} . } select TRIV= . show op _=_ . --> ---------------------------------------------------------------- --> parametrized list with _=_ --> ---------------------------------------------------------------- mod! LIST= (X :: TRIV=) { pr(LIST(X)) -- equality on List op _=_ : List List -> Bool {comm} . eq (nil = (E2:Elt | L2:List)) = false . eq ((E1:Elt | L1:List) = (E2:Elt | L2:List)) = (E1 = E2) and (L1 = L2) . } select LIST= . show op _=_ . #| ................................(_ = _)................................ * rank: *Cosmos* *Cosmos* -> Bool - attributes: { comm prec: 51 } - axioms: eq (CUX = CUX) = true eq (true = false) = false * rank: Elt Elt -> Bool - attributes: { comm prec: 41 } - axioms: eq (CUX = CUX) = true * rank: List List -> Bool - attributes: { comm prec: 41 } - axioms: eq (nil = (E2:Elt | L2:List)) = false eq ((E1:Elt | L1:List) = (E2:Elt | L2:List)) = ((E1 = E2) and (L1 = L2)) eq (CUX = CUX) = true |# -- you should declare _=_ on each sort -- like 'op _=_ : Elt Elt -> Bool {comm} .' -- 'op _=_ : List List -> Bool {comm} .' -- if you use _=_ in parameterized modules -- 'open LIST=(PNAT) .' causes errors -- because there is no op with rank 'Nat Nat -> Bool' --> ---------------------------------------------------------------- --> PNAT with _=_ on Nat --> ---------------------------------------------------------------- mod! PNATe { pr(PNAT) op _=_ : Nat Nat -> Bool {comm} . } select PNATe . show op _=_ . open LIST=(PNATe) . show . red 0 | nil = nil . red s 0 | nil = 0 | nil . red s 0 | nil = s 0 | nil . close --> ---------------------------------------------------------------- --> PNATe with equations --> ---------------------------------------------------------------- mod! PNATe= { pr(PNATe) eq (0 = s Y:Nat) = false . eq (s X:Nat = s Y:Nat) = (X = Y) . } select PNATe= . show op _=_ . open LIST=(PNATe=) . show . red 0 | nil = nil . red s 0 | nil = 0 | nil . red s 0 | nil = s 0 | nil . close --> ---------------------------------------------------------------- --> order-sorted PNATnz with _=_ and _==_ --> ---------------------------------------------------------------- mod! PNATnzee { pr(PNATnz) op _=_ : Nat Nat -> Bool {comm} . op _==_ : Nat Nat -> Bool {comm} . } open LIST=(PNATnzee{sort Elt -> Nat}) . show . red 0 | nil = nil . red s 0 | nil = 0 | nil . red s 0 | nil = s 0 | nil . close open LIST=(PNATnzee{sort Elt -> Nat,op _=_ -> _==_}) . show . red 0 | nil = nil . red s 0 | nil = 0 | nil . red s 0 | nil = s 0 | nil . close -- giving a view a name view TRIV=toPNATnzee from TRIV= to PNATnzee { sort Elt -> Nat, op _=_ -> _==_ } open LIST=(TRIV=toPNATnzee) . show . red 0 | nil = nil . red s 0 | nil = 0 | nil . red s 0 | nil = s 0 | nil . close --> **************************************************************** --> Describing op map with expressions in a view expression --> **************************************************************** -- open LIST=(PNAT) . -- open LIST=(PNAT{op _=_ -> _=_}) . -- eigher of the above two causes an error -- but the following works open LIST=(PNAT{op E1:Elt = E2:Elt -> E1:Nat = E2:Nat}) . red 0 | nil = nil . red s 0 | nil = 0 | nil . red s 0 | nil = s 0 | nil . close -- the following causes an error -- open LIST=(PNAT{op _=_ -> _==_}) . -- but the following works open LIST=(PNAT{op E1:Elt = E2:Elt -> E1:Nat == E2:Nat}) . show . red 0 | nil = nil . red s 0 | nil = 0 | nil . red s 0 | nil = s 0 | nil . close -- another example --> target of an operator can be any complex term open LIST=(NAT{op (E1:Elt = E2:Elt) -> ((E1:Nat <= E2:Nat) and (E1:Nat >= E2:Nat))}) . show . red 0 | nil = nil . red 1 | nil = 0 | nil . red 1 | nil = 1 | nil . close --> **************************************************************** --> module expressions --> **************************************************************** --> renaming sort and op open LIST(PNATnz{sort Elt -> Nat})*{sort List -> ListOfPnat, op _|_ -> _$_} . parse s 0 $ nil . close --> rename and module sum open LIST(PNAT)*{sort List -> ListOfPnat} + LIST(PNAT)*{op _|_ -> _$_} . parse s 0 | nil . parse s 0 $ nil . close --> rename and module sum open LIST(PNAT) + LIST(PNAT)*{sort List -> ListOfPnat} . parse s 0 | nil . -- error: ambiguous parse (s 0 | nil):List . parse (s 0 | nil):ListOfPnat . close -- giving a module a name to avoid sort ambiguity make LISTofPNATnz (LIST(PNATnz{sort Elt -> Nat})) make LISTofPNAT (LIST(PNAT)) open LISTofPNATnz + LISTofPNAT . parse (s 0 | nil):List . -- error: ambiguous parse (s 0 | nil):List.LISTofPNATnz . parse (s 0 | nil):List.LISTofPNAT . close -- sum of the same mudule expressions -- only create one module; -- no duplication of the module open LIST(PNAT) + LIST(PNAT) . parse s 0 | nil . close -- no way to escape, avoid this mod 2LISTofPNATa { pr(LIST(PNAT)) pr(LIST(PNAT)) } open 2LISTofPNATa . parse (s 0 | nil):List . -- error: ambiguous close -- no problems mod 2LISTofPNATb { pr(LISTofPNAT) pr(LISTofPNAT) } open 2LISTofPNATb . parse s 0 | nil . close --> ---------------------------------------------------------------- --> PAIR --> ---------------------------------------------------------------- mod! PAIR (X :: TRIV, Y :: TRIV) { [Pair] op _,_ : Elt.X Elt.Y -> Pair {constr} . } open PAIR(NAT,NAT) . parse 1 . parse 1,2 . close -- open PAIR(PAIR(NAT,NAT){sort Elt -> Pair}, -- PAIR(NAT,NAT){sort Elt -> Pair}) . -- creates two different sorts with -- the same name Pair and causes an error -- because the duplication of the two same module expression -- PAIR(NAT,NAT) creates two different module objects with -- the same sorts and ops -- by giving a name to a module exp PAIR(NAT,NAT), -- you can avoid this problem --> ---------------------------------------------------------------- --> PAIRofNAT --> ---------------------------------------------------------------- mod! PAIRofNAT { pr(PAIR(NAT,NAT)*{sort Pair -> PairOfNat}) [Nat < PairOfNat] } select PAIRofNAT . parse 1 . parse 1,2 . --> ---------------------------------------------------------------- --> PAIRofPAIRofNAT --> ---------------------------------------------------------------- mod! PAIRofPAIRofNAT { pr(PAIR(PAIRofNAT{sort Elt -> PairOfNat}, PAIRofNAT{sort Elt -> PairOfNat}) *{sort Pair -> PairOfPairOfNat}) [PairOfNat < PairOfPairOfNat] } select PAIRofPAIRofNAT . parse 1 . parse 1,2 . parse 1,(1,2) . parse (1,2),2 . parse (1,2),(1,2) . --> ---------------------------------------------------------------- --> PAIRofPAIRofPAIRofNAT --> ---------------------------------------------------------------- mod! PAIRofPAIRofPAIRofNAT { pr(PAIR(PAIRofPAIRofNAT{sort Elt -> PairOfPairOfNat}, PAIRofPAIRofNAT{sort Elt -> PairOfPairOfNat}) *{sort Pair -> PairOfPairOfPairOfNat}) [PairOfPairOfNat < PairOfPairOfPairOfNat] } select PAIRofPAIRofPAIRofNAT . parse 1 . parse 1,2 . parse 1,(1,2) . parse 1,(1,(1,2)) . parse (1,2),(1,(1,2)) . parse ((1,2),(1,2)),((1,2),(1,2)) . --> **************************************************************** --> end of file eof --> ****************************************************************