-- ==========================================================
--> 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
-- ==========================================================