class p2d

    x, y: int

predefined

    origin(0, 0)
    xaxis(1, 0)
    yaxis(1, 0)

end


class p3d inherit p2d

    z: int

predefined

    origin(0, 0, 0)
    xaxis(1, 0, 0)
    yaxis(0, 1, 0)
    zaxis(0, 0, 1)
end


class point1{a}

    from_point1: bool := false

noncreation

    test(x: int): int require x > 1 end := 1

end


class point2{a} inherit point1{a}

    from_point2: char

invariant

    1 <> 2

noncreation

    test(x: int, t: int := 6): int require x > 2 end := 2

end


class point3{a} inherit point2{a}

invariant

    algor(5) = 4

noncreation

    test(x: int, googol, t: int := 6): int require x > 3 end := 3

    algor(y: int): int :=
      let
         x := 2
         z := 3
      in
         x + z
      end

    int_case(x: int): int :=
      case x
        when 5 yield 0
        when 7 .. 9, 11 yield 1
        when 10 yield 2
        else 99
      end

    string_case(x: string): int :=
      case x
        when "a" yield 0
	when "b" .. "cc" yield 1
	else 2
      end

    month_case(x: int, leap_year: bool): int :=
      case x
        when 9, 4, 6, 11 yield 30
	when 2 yield if leap_year then 29 else 28 end
	else 31
      end

    roots(a, b, c: real): pair{real, real} :=
      let
         sqrt(x: real) := if self.from_point1 then x else 0.0 end
         sqrt_disc: real := sqrt(b*b - 4*a*c)
      in
         pair((-b + sqrt_disc) / (2*a), (-b - sqrt_disc) / (2*a))
      end

    fold(a: list{int}): int := a.fold(int!*, 0)

    test_indent: int :=
      if 1 = 2 then
        let x := 5 in x + x end
      elsif let y := 2 in y = y end then
        5
      elsif 0 = 0 then
        6
      else
        99
      end

    test_array: int :=
      let
        zulu := [||]
      in
        5
      end

    test_let_1: int :=
      let
        fib(n: int):int := if n <= 1 then n else fib(n-1) + fib(n-2) end
      in
        fib(5)
      end

    test_let_2: bool :=
      let
	start := 2
	even(m: int): bool := if m = start then true else m div 2 = 0 end
	odd(n: int): bool := even(n-1)
      in
        odd(5)
      end

    test_let_3: bool :=
      let
	start := 2
	odd(n: int): bool :=
	  let
	    even(m:int): bool := if m = start then true else odd(m-1) end
	  in
	    even(n-1)
	  end
      in
        odd(5)
      end

    test_case(cb: char_basic): int :=
      case cb

        when char_basic!L yield 0
        when char_basic!M yield 1
        when char_basic!N yield 2
        when char_basic!P yield 3
        when char_basic!S yield 4
        when char_basic!Z yield 5
        when char_basic!C yield 6
        when char_basic!I yield 7

      end

end
