-- This file was inspired from our development of
-- SimpleTags.prg. I realized
-- that the the shape and type indexes could be pushed into the
-- Label type, in that way the Count type was not needed.

-- A, B, C, and D are types, that will appear
-- as indexes in other types.

data Tag':: *1 where
  A:: Tag'
  B:: Tag'
  C:: Tag'
  D:: Tag'

-- A Shape is a list or record structure in which
--  A, B, C, and D are the labels.

data Shape:: *1 where
  E :: Shape
  P :: Tag' ~> *0 ~> Shape ~> Shape
    deriving Record(s)

-- A label is a value (i.e. data manipulated by a program)
-- That reflects which variable it reprsesents

data Label' :: Shape ~> *0 ~> *0  where
  A:: Label' { A=t; more}s t
  B:: Label' { a=x, B=t; more}s t
  C:: Label' { a=x, b=y, C=t; more}s t
  D:: Label' { a=x, b=y,c=z, D=t; more}s t

-- A Term is indexed by a Shape which determines what
-- variables are used in the term, and what type those
-- variables have.

data Term:: Shape ~> *0 ~> *0 where
  Iconst :: Int -> Term sh Int
  Var:: Label' i ty ->  Term i ty
  Pair:: Term sh a -> Term sh b -> Term sh (a,b)

-- exercise, design a substitution function.

-- Comments
-- 1) We have only a finite number of variables
-- 2) We don't have any binding structures like lambda or let