-- ========================================================== --> CafeOBJ codes for lecture1 -- ========================================================== --> Peano style natural numbers mod! PNAT { [ Nat ] op 0 : -> Nat {constr} . op s_ : Nat -> Nat {constr} . -- equality over the natural numbers -- op _=_ : Nat Nat -> Bool {comm} . -- declared in EQL -- eq (X:Nat = X) = true . -- declared in EQL eq (0 = s X:Nat) = false . eq (s(X:Nat) = s(Y:Nat)) = (X = Y) . } -- "mod! PNAT {" indicates start of definition of module -- named "PNAT". The definition ends at "}". -- "[ Nat ]" is a declaration of a sort (i.e. set of -- objects) named "Nat". -- "op 0 : -> Nat {constr} ." is a declaration of operator -- named "0" with no argument and return value of sort -- "Nat". That is, "0" is a constant of sort "Nat". "0" -- has an attribute of constructor indicated by -- "{constr}". The last "." can be omitted. -- "op s_ : Nat -> Nat {constr} ." is a declaration of -- constructor operator named "s_" with an argument of sort -- "Nat" and return value of sort "Nat". "_" in "s_" -- indicts the position where the argument is placed. -- Equality operator "_=_" is declared in built-in -- meta-module EQL as -- "pred _ = _ : *Cosmos* *Cosmos* { comm prec: 51 }". -- It is equal to -- "op _ = _ : *Cosmos* *Cosmos* ->Bool { comm prec: 51 }". show EQL . -- EQL is automatically imported into any user defined module, -- and _=_ is available for any sort. -- It implies that the following two declarations -- "op _=_ : Nat Nat -> Bool {comm} ." -- "eq (X:Nat = X) = true ." -- hold in "PNAT". -- "{comm}" indicates that the binary operator "_=_" is -- commutative operator, i.e. -- ((X:Nat = Y:Nat) = (Y = X)) -- holds. -- "eq (X:Nat = X) = true ." is a declaration of an -- equation. This equation means that for any object "X" -- of sort Nat, "X = X" is equal to "true". "X:Nat" is an -- on-the-fly declaration of variable "X" and the scope of -- this variable ends at the end of this equation. "." at -- the end and a space before it are must. select PNAT . red s 0 = s s 0 . red s 0 = s s s 0 . red s `n:Nat = s s `n . --> PNAT with plus _+_ operation mod! PNAT+ { pr(PNAT) op _+_ : Nat Nat -> Nat {r-assoc} . vars X Y : Nat . eq 0 + Y = Y . eq (s X) + Y = s(X + Y) . } -- "pr(PNAT)" indicates the importation of module "PNAT" -- into this module with the importation mode of "pr" -- (i.e. protecting). "pr" indicates that the module -- "PNAT+" refers the module "PNAT" as a sub-module, and can -- use any entities declared in the module "PNAT". -- "{r-assoc}" indicates that the operator "_+_" associate -- to right. This is just for parsing terms. -- "vars X Y : Nat ." is a declaration of variables "X" and -- "Y" of sort "Nat". The scope of these variables ends at -- the end of the module. "." at the end can be omitted. -- ========================================================== --> special charactors of CafeOBJ -- ========================================================== -- Eight charactors "(" ")" "[" "]" "{" "}" "," ";" are -- self-terminating characters of CafeOBJ. A -- self-terminating charactor is a printable ASCII character -- which by itself constitutes a token. You do not need to -- put spaces before and after these characters. -- Two charactors of "(" ")" are meta-charactors of CafeOBJ -- language, and should be used only for grouping -- terms/expressions. These charactors can not be used in -- any kind of identifiers. ** ========================================================== --> verification of the properties about _+_ ** ========================================================== -- ========================================================== --> Proof score for righ zero property: --> (N:Nat + 0 = N) -- ========================================================== **> Proof of (N:Nat + 0 = N) by induction on N:Nat **> induction base case: -- opening module PNAT+ to make use of all its contents open PNAT+ . red 0 + 0 = 0 . close **> induction step case: -- opening module PNAT+ to make use of all its contents open PNAT+ . **> declare that the constant n stands for any Nat value op n : -> Nat . **> induction hypothesis: eq n + 0 = n . **> induction step proof for (s n): red s n + 0 = s n . close **> QED {end of proof} -- ========================================================== -- "open PNAT+" opens the module "PNAT+" and creates a -- temporal module which can use all entities in -- "PNAT+". The created temporal module is discarded by -- "close". -- "op n : -> Nat ." is an operator declaration inside -- "open" and "close", and the last "." is a must. This is -- different from an operator declaration inside a module -- definition. -- "red 0 + 0 = 0 ." and "red s n + 0 = s n ." are reduction -- commands, and return the most simplified expression of "0 -- + 0 = 0" and "s n + 0 = s n" by using all avairable -- equations of the module "PNAT+" as rewrite rules from -- left to write. -- ========================================================== --> Proof score for associativity of (_ + _) --> (N1:Nat + N2:Nat) + N3:Nat = N1 +(N2 + N3) -- ========================================================== **> Proof of associativity: **> (N1:Nat + N2:Nat) + N3:Nat = N1 +(N2 + N3) **> by induction on N1 **> induction base case: open PNAT+ . red 0 + (`n2:Nat + `n3:Nat) = (0 + `n2) + `n3 . close **> induction step case: open PNAT+ . **> declare that the constant n1 stands for any Nat value op n1 : -> Nat . **> induction hypothesis: eq (n1 + N2:Nat) + N3:Nat = n1 + (N2 + N3) . **> induction step proof for (s n1): red ((s n1) + `n2:Nat) + `n3:Nat = (s n1) + (`n2 + `n3) . close **> QED {end of proof} -- ========================================================== -- `n2:Nat and `n3:Nat in "red" (reduction) command are -- on-line (or on-the-fly) declarations of fresh constants -- whoes scopes end at the end of the "red" command. -- The on-the-fly fresh constants in a "red" command -- should start with a back quote charactor "`". -- ========================================================== --> comments in CafeOBJ codes -- ========================================================== -- line starts with "-- " or "** " is a comment line --> line starts with "--> " and "**> " are comment lines with --> echo backs from CafeOBJ system. That is, the system --> print out these lines if this file is inputed into the --> system. -- Text starts with #| and ends with |# is a comment. -- ========================================================== --> parsing term with precedences and {r-assoc} attribute -- ========================================================== -- selecting PNAT select PNAT parse s s 0 . reduce s s 0 . -- "parse s s 0 ." is a command to parse the term "s s 0" select PNAT+ . parse s 0 + 0 . parse s 0 + 0 = s 0 + 0 . parse s 0 + 0 = s s 0 + s 0 + 0 . show tree describe op s_ describe op _+_ describe op _=_ describe mod tree PNAT+ sh op s_ sh op _+_ sh op _=_ sh ops sh all ops -- It is better to put enough parentheses and make the term -- structure clear! Do not play with parsing with -- precedences too much! -- ========================================================== -- Order sorted Peano style natural numbers -- and error handling -- ========================================================== --> Order sorted Peano style natural numbers mod! PNATord { [ NzNat < Nat] op 0 : -> Nat {constr} . -- successor op s_ : Nat -> NzNat {constr} . -- predecessor op p_ : NzNat -> Nat . eq p s N:Nat = N . -- equality eq (0 = s(N2:Nat)) = false . eq (s(N1:Nat) = s(N2:Nat)) = (N1 = N2) . } -- "[ NzNat < Nat]" indicates that the sort "NzNat" -- is included in the sort "Nat". --> error handling with ordered sorts select PNATord . -- (p 0) is a term of error sort parse p 0 . red p 0 . parse p s 0 . red p s 0 = 0 . parse p p s 0 . red p p s 0 = 0 . -- this reduction shows an example of -- error handling with ordered sorts -- ========================================================== --> Difference of _=_ and _==_ -- ========================================================== -- opening PNAT open PNAT . parse 0 = s 0 . red 0 = s 0 . op n : -> Nat . red n = n . red 0 = n . red 0 == n . close -- NAT is built-in module of natural numbers. The module -- NAT contains (1) sort Nat which is a set of infinite -- natural numbers, and (2) ordinary fundamental operations -- over Nat. show NAT . mod! GOOD-POS{ pr(NAT) pred positive : Nat var N : Nat eq positive(N) = not(N = 0) . } mod! BAD-POS{ pr(NAT) pred positive : Nat var N : Nat eq positive(N) = not(N == 0) . } -- Proof scores for "positive(n) for all Nat n" -- (This is not true) . open BAD-POS . op n : -> Nat . red positive(n) . close -- Proof scores for "positive(n) for all Nat n" -- (This is not true) . open GOOD-POS . op n : -> Nat . red positive(n) . close -- Proof scores for "positive(n) if ((n = 0) = false) -- (This is true) . open GOOD-POS . op n : -> Nat . eq (n = 0) = false . red positive(n) . close -- ========================================================== --> end end end -- ==========================================================