Start of topic | Skip to actions

Writing Existentials in Concoqtion and Other Tricks to Write Functions on Sized Lists

Scribe: Joseph Young

Existentials in Concoqtion

We would like to write a size_it function on sized lists that takes an unsized list as an input and returns a sized list as an output. This provides an interesting challenge since we don't want to specify the size of the sized list when we call the function. In other words, we want the type of this function to be
      size_it 'a list -> there_exists n. ('a,n) slist
Unfortunately, Concoqtion does not contain existential qualifiers, so we need to use a trick to encode one.

Given two statements P and Q where P depends on x, but Q does not depend on x. We will show that
      (there_exists x.P(x))=>Q <==> for_all x. P(x)=>Q
This will allow us to reencode the existential qualifier as a universal qualifier that Concoqtion supports. In the left hand side, we rewrite the implication as
      not(there_exists x.P(x)) or Q
But, the negation of the statement, "there exists an x such that P is true" is simply, "for all x, P is false." Thus, we can rewrite the above statement as
      (for_all x.not(P(x))) or Q
Since Q does not depend on x, we can move it within the universal qualifier which yields
      for_all x.not(P(x)) or Q
which is simply an alternative formulation of an implication. Thus, we have that
      for_all x.P(x)=>Q
Therefore, we have confidence that we can transform and existential qualifier into a universal qualifier.

In our case, we use this idea by creating a new datatype called exists_size with definition

type ('a) exists_size=E of let 'n:'(nat) in ('(n),'a) listl
Therefore, the size_it function will have a definition of let size_it (xs:'a list) : ('a exists_size)= Essentially, this allows us to encapsulate the size information within another datatype. If we had the definition
let size_it (xs:'a list) : (('(n),'a) slist)=
we would need to specifiy the size of slist before hand. When we use the existential trick, we don't. Of course, this also changes how we can use the output from the size_it function. Since the output from the function is no longer a sized list, we have to use a match statement to access the data. For example,
let _ =match (size_it x) as 'a exists_size in unit with
    | E .|n:'(nat)| slist->
This means that we can only access the size information from within the match statement.

Option and Singleton Types

We would like to write a function called at_size that takes a regular list and a number representing a size. Then, the function returns a sized list with the specified size. The trouble with this function is that the user may specify a size that is larger than the original list. In this case, we need a method to correctly trap the error. Thus, we introduce an option type.

We can define an option type by

type 'a my_option=None | Some of 'a;;
When there's an error, we return None, otherwise, Some. Unfortunately, we will need to check if we have Some or None later.

In addition, we will need to make use of a singleton nat. Singleton types are types where we can completely determine their value during type checking. We use these types since we are interested in using the size of the list as a value. Since the size of the list is a type, we can't use it as a value directly. We can define a singleton natural with the following definition

type 'm:'(nat) snat=
| Z: '(0) snat
| S of let 'm:'(nat) in '(m) snat : '(S m) snat
;;
An example of a function that takes a snat and sums it's values is given by
let rec sum_snat .|n:'(nat)| (my_snat:('(n) snat)) (my_num:int) : int  =
    match my_snat as 'm:'(nat) snat in int with
    | Z -> 0
    | S .|m:'(nat)| x->my_num+(sum_snat .|'(m)| x (my_num+1))
    ;;
We can use this function to see how it works
# let a=S .|'(2)| (S .|'(1)| (S .|'(0)| Z));;
let _=sum_snat .|'(3)| a 1;;
val a : '(3) snat = S (S (S Z))
# - : int = 6

Need to finish at_size here

-- JosephYoung - 01 Feb 2007


End of topic
Skip to actions | Back to top
Creative Commons LicenseThis work is licensed under a Creative Commons Attribution 2.5 License. Please follow our citation guidelines.