1.1 Discrete versus Continuous Mathematics.
Debates surrounding continuous versus discrete mathematics arise in many subdisciplines of the mathematical sciences. Where this debate is of paramount importance can be found in the general area of computer modeling of real world applications. While we will not be discussing any specific computer model in great detail, it is appropriate that we at least start with some background to this topic since it largely represents the motivation behind much of the discourse presented throughout this book.
Computer modeling has become an important component of many scientific studies. However, despite its widespread use in the sciences, computer modeling still has a reputation of taking on aspects of an art rather than an exact science. The reasons for this reputation are somewhat historic. While this field has provided many useful results and enhanced insights into a wide area of scientific research there still remain weaknesses in the validation of computer models at a theoretical level.
The difficulties largely originate from two, not entirely unrelated, sources. The controversy surrounding the existence of the real numbers, , is a philosophical debate that has been around since antiquity. More recently, the existence of infinite sets, that are the basis of many mathematical abstractions, is also one that is contested in the philosophical arena. From the perspective of raw computations on a real world deterministic computer there is no philosophical issue. A machine neither recognizes an infinitesimal nor infinite sets in general.
Pure mathematicians are motivated by structures that have an elegant representation in the platonic world of ideal forms and have very little interest in real world applications. In this realm the construction of the reals along with other mathematical abstractions involving infinite sets cannot be readily dismissed. While largely motivated by theoretical interest, the extensive products of the efforts of pure mathematicians over the years have nevertheless been found to be useful in the sciences.
It has been widely accepted that mathematics is the language of science but with this come compromises that are often overlooked. Mathematical structures are abstract constructions. In order to maintain some consistency, the physical system under investigation often needs to be idealized to suit the language that is employed to describe it. As with the construction of the language upon which it is based, the constructions of models of the physical world under such idealizations can lead to theories that take on the appearance of elegance. Unfortunately, the abstractions embedded in the descriptive language of contemporary mathematics can also lead to complications, as will now be discussed.
Following in the footsteps of many other scientists, computer modelers have often adopted the language of continuous mathematics without question. The constraints of the finite resources of the computer and its inability to recognize the reals and infinite sets in general have led to the acceptance of the computer as a tool of approximation. This in turn has led to the emergence of the discipline of numerical analysis that is largely dedicated to providing a rigorous foundation for approximation.
As an example, let us look at the wide application area of hydrodynamics. In particular we want to focus on the traditional procedures for model validation. We are concerned here with validation in the theoretical sense and this should not be confused with model validation that involves comparing simulation results with empirical data.
Hydrodynamics is largely based on conservation laws that are expressed in the form of second order partial differential equations (PDEs). The most widely used hydrodynamic computer models involve some kind of discrete system of equations that is meant to represent an approximation of the continuum theory. We can view this as a map that transforms a system of PDEs to a system of difference equations (DEs),
(1.1.1) 
Under this map the continuum model is regarded as the template that represents the exact description of the physical system being modeled. The discrete model attempts to approximate the continuum model by employing some type of discretization scheme. These include finite difference methods, spectral methods and other variants of discretization. Associated with any discretization scheme is a characteristic spatial resolution, , and in the case of time dependent problems a temporal resolution, .
The map (1.1.1) associated with the continuum to discrete model is regarded as valid if all of the following conditions are met.

The continuum model is well posed. The classical definition of a well posed system is based on the existence and uniqueness of a solution along with continuous dependence on the initial data.

Stability of the solution of the discrete system of equations.

The discrete system of equations converge to the continuum equations in the limit, , (consistency).

The solution of the discrete system converges to the solution of the continuum equations in the limit, , (convergence).
There are many mathematical theories that have been developed to address these items. To name a few are finite difference methods that are often based on Taylor expansions, weak or generalized formulations of PDEs and solution methods and stability analysis of DEs. Despite the extensive theoretical work on the subject, except for some special cases, a complete rigorous theoretical validation is rarely achievable.
The above conditions establish validity on theoretical grounds but do not entirely address the practical aspects of machine computation. The exact solutions of the theoretical discrete system will not necessarily coincide with that of the discrete system implemented on the machine. This is because we are forced to employ floating point arithmetic. Thus round off errors introduce another complication that needs to be considered if a complete model validation is demanded.
Matters become even worse when we find that often it is difficult to establish that the continuum model itself is well posed. A case in point is the NavierStokes equation upon which fluid mechanics is based. It is currently unknown whether there exist smooth unique solutions of the NavierStokes equation in three dimensional space that satisfy typical boundary and initial data.
First, it is worthwhile examining the origins of the continuum model. The most fundamental continuum theories are based on the Euler equations of an ideal fluid. Here the laws of fluid flow are derived largely from the primary properties of a continuum. In applications the Euler equations are replaced by equations that include terms associated with viscosity, heat transfer and other phenomena that may be deemed important for the particular problem being considered. This class of semiempirically based continuum equations of hydrodynamics are derived from a particle model through the application of Boltzmann equations that employ continuous distributions. We can represent this as a map under the action of Boltzmann statistics
(1.1.2) 
Thus the continuum model itself is derived from a microscopic scale discrete system. The combination of the maps (1.1.1) and (1.1.2) is then a two step procedure of discrete to continuous back to discrete. A striking feature of this procedure is that the properties of the two discrete systems are very different.
In light of these observations one may ask whether it is not better to compare the computer model directly with the kinetic particle model. Both are discrete systems and the existence of solutions of the formulation associated with the particle model is much more tractable.
Fortunately, this idea has, in some sense, been around since the advent of the first computers. Cellular automata have been used to model many complex systems ranging from applications in the biological sciences to networks of information flow. In more recent decades has emerged the use of cellular automata in the area of hydrodynamics. The popularity of cellular automata in this application area has waxed and wained over the years but the results that they produce cannot be readily dismissed and are worthy of continued examination.
Cellular automata in fluid dynamics are discrete rule based algorithms that attempt to mimic the particle model. As such they can be directly translated into a computer program. The fluid medium is discretized into a lattice and within each cell of the lattice there are only two possible states, . The dynamics of the system is governed by a collection of simple deterministic rules of cell pair interactions. The primary and defining feature of such systems is the conservation of information that reflects the physical law of conservation of mass.
For cellular automata to be effective the spatial domain needs to be discretized into a very large number of small cells. But even with the smallest possible refinement on the most powerful computers, the characteristic size of the cells is still very much larger than the mean free path of the particles that it is meant to simulate. This suggests that allowing only two states per cell may be inadequate.
Issues of scale inconsistencies also arise in the formulation of continuum models. In the early days of computational fluid dynamics it was found that the discrete models based on the NavierStokes equation did not perform well for large Reynolds numbers. (Large Reynolds number flows are associated with the onset of hydrodynamic instabilities leading to turbulence.) The earliest attempts to remedy this situation involved the introduction of a turbulence viscosity term that was identical in form to the molecular viscosity term. While there were some improvements in simulation results, the introduction of the turbulence viscosity constant appeared to be inadequate to capture observed flows where a high degree of accuracy was required. This led to the area of large eddy simulation models where the constant turbulence viscosity coefficient was replaced by a variable, usually based on a function of the deformation tensor (see for instance
[1]). The so called Smagorinsky model [2] introduced in the 1960s remains the most popular model whose variants are still in use to this day.The problem with fluid turbulence models based on large eddy simulation is their dependence on artificial parameters that need to be readjusted for each specific application. The presence of these artificial parameters is an indication that the continuum model exhibits some type of inconsistency. One can identify this inconsistency as arising from the fact that the continuum model is ill defined in the sense that it fails be scale invariant.
The important properties that would be demanded from a reformulation is that it be scale invariant and be independent of artificial parameters that require tuning to specific applications. One way to do this is to accept that the dependent variables of the continuum equations are filtered variables that must not only be dependent on space and time but on a new independent variable associated with scale. One introduces the following conditions that define consistency based on scale invariance [3][7].

The macroscopic formulation is described by a system of equations that represent conservation laws of the filtered variables and contain residual terms that capture all of the dissipative and dispersive effects that are associated with microscopic scale fluctuations. The macroscopic scale formulation must be form invariant with respect to scale.

The dependent variables of the macroscopic formulation must also satisfy the filter equations that are expressed as second order partial differential equations rather than integrals. It is convenient to use the spacescale heat equation for this purpose because its solutions can be associated with a Gaussian type spatial filter. The filter equations provide a continuous relationship of the filtered variables with respect to scale.

In the limit of increasing spatial resolution the residual terms vanish and the macroscopic equations collapse to the fully resolved continuum equations.
The third item becomes problematic for applications such as in fluid dynamics where there remains the uncertainty of the existence of any meaningful solutions of the fully resolved continuum equations. There have been attempts to address this by abandoning all together any notion of a fully resolved system (see for example [7][8]).
Close examination of the conditions for consistency of scale invariance suggests that a continuum formulation can be removed altogether. An important observation is that the scale parameter is proportional to the square of the desired characteristic spatial resolution, . Since this can be directly associated with the spatial resolution of the discretization that is employed in the computer model it appears reasonable to consider the possibility that one could discard the continuum model and adapt the above conditions for consistency based on scale invariance of an entirely discrete formulation.
To this end we must rely on the working hypothesis that the intrinsic properties and dynamic state of objects of the physical world can, at all scales, be defined in terms of information. Under this regime the conservation laws of the continuum theories are replaced by laws that govern the conservation of information in some form. Such a rule based algorithm involves finite state arithmetic as is reflective of computations on a real world deterministic machine. Here there is a major philosophical shift in that the discrete model is both the computer model and the template that defines the laws that govern the physical system being simulated. In this paradigm the traditional notions of validation by way of consistency, convergence and stability of a discrete computer model of a continuum theory is bypassed by the single property of computability of a program built upon sequentially ordered statements. By pursuing this path it will eventually become apparent that, by necessity, the discourse is transferred from the language of mathematical equations to the language of rule based algorithms and computer programs.
It should be stressed that the issue being discussed here is one of a choice of the most efficient language that can be employed to model the physical world. Whether we possess a language that is rich enough to allow us to completely describe the physical world will remain a controversial issue. We can, however, be encouraged by current trends in theoretical physics where there is an increasing tendency towards formulating physical laws in a language based on information, where physical objects and their dynamic state are represented by integers.
This is related to the general area of digital physics of which early proponents include Zuse [9] and Jaynes [10][11]. More recent proponents of digital physics include Wolfram [12] who explores the universe of the most elementary computer programs. Allied to this subject are the deeper mathematical investigations of Chaitin (see for example [13][22]) who is credited as a major pioneer of algorithmic information theory. Of particular note is Chaitin’s interest in the work dating back to Leibniz [23] who, apart from being the earliest known discoverer of binary arithmetic, appears to have explored early notions of complexity and how complexity can be employed to ultimately construct a formal definition of what actually constitutes a scientific theory. Using this as a starting point, Chaitin goes on to explain how this leads to the interesting idea that theories of science are best expressed in a language of programs. Some aspects of these works, along with the more controversial views of Zeildberger on finitism and discrete versus continuous mathematics (see for example [24][25]), are highly influential in some of the ideas presented throughout this book.
Continuum theories have so far served us very well, providing insights in many branches of scientific research. But their limitations in providing closed form solutions for many complex systems, and hence the need to introduce discrete approximations along with their inherent problems, are increasingly becoming recognized. In a future where greater rigor is demanded in modeling complex systems, alternatives need to be investigated. A language based on programs and its association with discrete mathematics appear to provide a good candidate for such an alternative.
It will be premature here to embark on a detailed review of methodologies associated with the construction of fully discrete models of specific real world applications. Before we can do this we must first reassess the very foundations of basic arithmetic on a deterministic machine with finite memory. Indeed, the axioms that dictate the basic rules of machine arithmetic will play an important role in defining the laws that govern the construction of the discrete model. If we are to seriously take the discrete model as the defining language that describes a real world application then it is not unreasonable to expect that the conventional laws of physics will emerge as manifestations of the more fundamental laws of allowable finite state computations. In this book we will explore some of these ideas, starting with the most elementary laws that govern machine arithmetic. From such a study it is hoped will emerge a platform from which a formal and rigorous approach to computer modeling can be constructed.
To this end we adopt an alternative to the traditional approach of proofs based on abstract mathematical structures. We start by introducing an inference scheme based on the so called program extension rule. This formal system is a departure from the traditional formal schemes of proof theory in that it is largely constructed from the rules that govern the allowable computational operations on a real world computer that is constrained by finite memory storage. The language that we will choose is one of representing formal statements as programs. Having constructed the foundational tools of inference we will then explore the constraints imposed by a deterministic machine with finite memory and the most elementary operations of arithmetic that can be performed on it. This will lead us to the exploration of computability of fully discrete dynamical systems as they are directly implemented on a real world deterministic computer.
1.2 Machine arithmetic.
Our main objective is to construct a formal language from which we can validate computer models on the basis computability. In the previous section we discussed discrete models based on simple deterministic rules but practical application often requires the necessity to reformulate these models on lattices that represent larger scales. It follows that the transformation from the microscopic to the macroscopic scale is associated with a transition from a rule based algorithm to one that is largely based on numerical computations.
It should be kept in mind that our goal for establishing computability is much higher than just avoiding underflows and overflows of the numerical computations. We start with the hypothesis that the fully discrete model, and hence the operational parameters that characterize the machine upon which the model is to be executed, are reflective of the underlying structure of the real world system. Under this hypothesis we are raising the status of the conditions of computability of a model by associating them with the laws that govern the dynamics of the real world system.
In any attempt to construct a tool for the validation of programs largely based on numerical computation one first looks to the basic foundations of arithmetic starting with the axioms of rings and fields (see for example [26], [27]). Unfortunately, when encountering machine arithmetic one will eventually observe a departure from the elementary rules of arithmetic upon which one has been accustomed. To explain some aspects of these departures one may delve deeper into analysis through topics such as modulo arithmetic and finite fields [27], but these too fall short of addressing many of the problems that are encountered when dealing with machine computations.
One promising approach that provides rigor through direct numerical computations can be found in interval arithmetic (see for example [28], [29]). This has found wide use in computations attempting to approximate continuum theories by way of floating point arithmetic. For discrete based models where integer or fixed precision rational solutions are desired, we can define discrete interval arithmetic in a similar way but with some important differences.
To tackle this problem in its entirety one soon finds the need to investigate topics in a much wider area, many of which are found in the realm of the computer sciences. In particular, the initial motivation of program verification evolves into an area involving inference methods in a more general sense.
Traditional studies of computers and computation often start by constructing a theoretical model that reflects some properties of real world computers. Such examples can be found in Turing machines along with abstractions of programming languages themselves such as lambda calculus
[30] leading to the study of logic and the important link between proofs and programs. The latter in turn leads one into the subject of proof theory. This is a wide area of study of which an excellent coverage can be found in [31].The formal systems in the general area of proof theory were primarily developed to address important theoretical problems in logic and were not optimally designed for practical implementation in a machine environment. The approach taken here is to construct a formal language such that the rules of inference are not dictated by an external abstract theory of logic but rather on the allowable computational operations on a real world computer. As a consequence there will be a need to abandon some of the expressiveness of formal systems found in current proof theory. Motivated by a more practical approach to program verification, the language is presented in a form that is less abstract than traditional studies of theoretical computers and programing based on the lambda calculus.
These methods will be described in the context of the software package VPC (Verification of Program Computation) in its current phase of development. While the source code of VPC will not be presented here, an effort will be made throughout this book to describe its internal algorithms in sufficient detail so that the reader will be equipped to construct their own version.
In the construction of our formal language the following properties are of primary importance.

Simplicity. The language should be simple and accessible to those of various backgrounds outside of the computer sciences.

Analysis. The simplicity of the language should not compromise its power to be employed as a tool of analysis at a sufficiently high level.

Proof assistance. As a language based on programs it should be readily implemented on a machine platform. As such, automated procedures can be constructed that assist in the generation of proofs. This assistance comes in the form of (i) generating on screen real time constructions of formulations that remove the laborious and error prone task of writing down symbols on paper and (ii) a step by step guidance of valid options in a proof construction.

Compatibility. A language that is specially designed to address the issues of computability on a real world computer, with particular focus on models based on finite state arithmetic. It is also advantageous to converse in a language that closely resembles the actual code that will ultimately represent the computer model.

Expressiveness. The language will largely deal with objects as subtypes of strings that are immediately recognized by the machine. Consequently, it will be a low level language that will lack the expressiveness found in standard formal systems of proof theory. However, it should possess the properties that it can be used as a primitive upon which theories demanding higher levels of abstractions can be built.

Improvements.
The language should be flexible enough to be open for future developments that extends its scope for analysis. Towards the more ambitious goal found in the area of artificial intelligence there exists the potential to explore avenues that ultimately lead to complete automation.
2.1 Types.
We shall deal with objects and types, where each object has a type. In a machine environment each object is identified by a single string. Different string structures are associated by their type.
Properties of types.

Object has type is denoted by . Types will always be written in bold symbols.

An object may also be dependent on other objects. We write to mean that the object depends on the objects or parameters , where need not be of the same type.

Types may be subtypes of types. Type is a subtype of is denoted by
Subtypes have the property that if and then . It follows that if and then .

Types may also be dependent on objects. We write to mean that type depends on the parameters or objects . Parameter dependent types are subtypes of their generic type, i.e.
Note that if and are parameter dependent types and it does not necessarily follow that is a subtype of .
2.2 Alphabet and strings.
Here we shall work in a machine environment based on a real world deterministic computer. A real world deterministic computer is characterized by the properties of finite information storage along with a finite collection of well defined operations. At any time the machine can exist in any one of a finite number of configuration states. A program is a sequentially ordered list of instructions where each instruction attempts to map the current configuration state to a new configuration state. The context in which we will choose to work can be defined by the following machine specific parameter constraints.
number of characters in the alphabet.  (2.2.1)  
maximum number of characters in any string.  
maximum number of elements of a list.  
maximum absolute machine integer. 
We define the list of machine parameters by
(2.2.2) 
(All lists will be enclosed by square brackets and elements of a list are separated by a space). The choice of the parameters of are very much dependent on the physical storage capacity of the machine. As outlined in the next section, the maximum list length, , applies also to multidimensional arrays since they can be stored as partitioned lists.
We will explore the computational processes that are entirely confined within a machine environment, , under the machine specific constraints, . Where it is necessary to stress this context we will write
We start by defining the alphabet as a collection of symbols or characters
The alphabet that we will work with consists of the following characters.

Letters.

Digits.

Special characters.
Strings.

A string of the alphabet is a sequence of characters

A single string defines an object and is given a generic type denoted by . Different string structures are identified as subtypes of .

There are two important subtypes of strings.

, alphanumeric strings comprised of any combination of letters and digits with the first character always being a letter.

, signed integers comprised of digits preceded by a sign .

Other subtypes will be defined as they are encountered throughout this book. Sometimes we will allow a space to be included in an individual string. In such a case the space will be regarded as a special character.
Alphanumeric strings. Alphanumeric strings are assigned the type and are often used to represent names of programs and variable names of elements of the input/output (I/O) lists of programs. Variable names of the elements of I/O lists of programs serve as place holders for assigned values that are defined as specific types within the program. We write to stress that
is a dummy variable that represents an alphanumeric string. Upon entry to a program we may also write
to denote that the alphanumeric string represented by the dummy variable has been assigned a value of type . The assigned value can be any object of a well defined type.Equality. There is an important distinction that needs to be made with the notion of equality.

If and are dummy variables representing two strings we write to mean that the two strings are identical. The sense in which equality is being used here will always be assumed unless otherwise stated.

We may also write to mean that the assigned value of the alphanumeric string represented by the dummy variable is identical to the assigned value of the alphanumeric string represented by the dummy variable . The sense in which equality is used here will always be stated to avoid confusion.
Machine numbers. An object of type is a string that can be assigned any one of the integer values
We shall make extensive use of the following subtypes of .
We adopt the usual convention of dropping the prefix sign when dealing with positive integers.
One of our objectives is to describe the program VPC as a tool for analysis and verification of numerical computation. For the purpose of demonstration only we will restrict much of the outline to machine integer arithmetic. It will be seen later that most of the results using machine integers can also be applied to fixed precision rational numbers. It should be kept in mind that VPC has a much wider area of application that includes floating point arithmetic. The reasons for excluding floating point arithmetic is based on the anticipated paradigm shift in computer modeling as discussed in the introduction of Chapter 1.
2.3 Lists.
Throughout we shall work with lists rather than sets. Many properties of lists, such as list intersections and sublists, will have strong similarities with those used in set theory. For this reason much of the notation used in set theory will be adopted for lists. Since we are working in an environment all lists will be of finite length.
Type.
Properties of lists.

A list , has the representation
We use a space instead of a comma to separate elements of a list. The notation
means that is an element of the list . The object is referred to as the length of the list . We write
where is the list length function.

Elements of lists are objects that may be identified by a single string or may themselves be lists (see next section).

An empty list is denoted by . If, under the list representation , we have then it is understood that is the empty list.

For a list, , of unit length we will sometimes write and to mean the same thing, i.e.

Elements in a list need not all be assigned values of the same type.

List equality. If and , , and , , we write . We use equality in both senses of identity of strings and the values assigned to the strings. Throughout, unless otherwise stated, equality will be assumed to be in the sense of the former, i.e. in the sense of the identity of strings. Whenever the equality is used in the sense of assigned values it will be stated as such.
List operations.

List concatenation. If and are two lists then the concatenation of and yields the list given by
The internal square brackets that act as delimiters for the lists and may be removed.

List intersection. If and then the list intersection of and yields a new list , , where contains all of the elements that are common to both and . We write
to mean that is the list intersection of and . Whenever a list intersection is constructed, the sequential order of the elements of are in the same hierarchy of the sequential order that they appear in .

Removal of repeated elements of a list. If has repeated elements we can construct a new list , , , by removing repeated elements as follows. Reading the list from left to right, whenever an element is encountered that coincides with a preceding element of then that element is discarded. In other words, each element of contains all nonrepeated elements of and the first occurrence of a repeated element of the list , as read from left to right, maintaining the order in which they appear in . We write
to mean that is obtained by extracting repeated elements of by this procedure.

List subtraction. Suppose that and . We can construct a new list obtained by extracting from those elements found in . The new list maintains the sequential order found in , i.e. , , , where are all of the elements of not found in . We write
to denote the new list constructed in this way.

Element substitution. For a list we write to denote substitution of the element with , i.e.

Empty list extraction. Suppose that , , contains an element that is an empty list, i.e. . We may extract the empty list element and write
After empty list extraction we can automatically redefine .
Sublists. Because of its importance, the notion of a sublist affords a more formal definition.
Definition 2.3.1.
(Sublist.) A list is a sublist of list if every element of is an element of , i.e. if then . We write to mean that is a sublist of . There are two cases that need to be distinguished.

If and then we say that is a strict sublist of . We write to stress that is a strict sublist of .

If and we say that the two lists are equivalent and write .
The empty list, , is regarded as a sublist of all lists.
Notes.

If is a sublist of it does not necessarily follow that . Consider the case and . In this example is a strict sublist of yet .

Similarly, two equivalent lists need not have the same length. For example and . Here and , hence .
2.4 Arrays as lists.
Integer vectors. An integer vector of dimension is a list whose elements have all been assigned the values of type . We use the notation to denote the type integer vector with the understanding that the vector dimension, , is type . When all of the elements of the vector have been assigned the value of type we write .
Sometimes we will refer to an object of type as an integer state vector or simply a state vector. When discussing fully discrete dynamical systems a state vector will be used to refer to an integer vector that is structured in such a way that it contains the minimum amount of information that is needed to completely describe the intrinsic properties and dynamic state of an object in the system at any given time. (In this context the term state vector should not be confused with that defined in quantum mechanics.)
Arrays. The definition of a list can be extended by allowing any element, , of a list to be a list. Elements of a list that are not lists are called atomic elements. Atomic elements that have type assignments (integers) or (rational numbers) are called scalars.
Lists of lists can be represented as arrays. We now demonstrate how arrays can be stored as partitioned lists.
When discussing arrays of general dimensions in a conventional mathematical language indexing can become cumbersome to write down. We will use some shorthand notation.
The array dimension list is defined by
Array dimension lists are fixed and will be used to define dimensions of arrays. The rank of an array is equal to the length of its dimension list. We write
to mean that is an array of rank with dimension list . In expanded form an element of an array, , can be written as , where is the index list given by
Sometimes it will be convenient to partition the dimension lists. We can define an array, , where we have combined two dimension lists, and . The rank of the array is and has the element representation .
List partitions. Arrays are stored as lists with a specific partition. The position of an element, , of an array, , in a single list is given by the list index
In this way we can always redefine an array, , as the list
where is a scalar.
Matrices. We can also express an array as a matrix. A matrix can be thought of as an array of rank two and is given the type , where . If , whose elements are given by , then we can construct the matrix , , where
Each element of the matrix , can be obtained from the array through the order index functions
Elements of arrays. Consider the list
Suppose that each element is itself a list
The list, , has the expanded form
(2.4.1)  
where the internal square brackets can be removed in the final expansion. We may write
(2.4.2) 
to mean is a sublist of and is an individual element of the list as represented by the expanded form of the last identity of the above concatenation (2.4.1).
Sometimes we may write
(2.4.3) 
to mean that is an element of the list of lists . The meaning here will be evident that we are treating as a list of elements that are type . Otherwise we would write with the meaning that the list of elements of is a sublist of the expanded list of elements . Where there might be confusion the sense in which an element of a list of lists is defined will be stated.
We may continue the expansion of (2.4.1) in the case that each is itself a list. In a similar way, defining elements and sublists of the list will depend on the context that we choose.
Notes.

Here we have borrowed the definitions of the rank and dimensions of an array from the programming language Fortran. This differs from the definition of the rank of a matrix as employed in mathematics.

We have defined an integer vector to be just a finite list of integers. In Chapter 7 we will examine such objects under the operations of addition, subtraction and scalar multiplication. However, because we a working in a machine environment, , it will become evident that such objects fail to obey many of the rules associated with contemporary vector spaces.

An integer vector will be referred to as a state vector when it is used to define the minimum amount of information necessary to completely describe the intrinsic properties of an object and its dynamic state at any given time in a real world system. Here we use time in a discrete sense that can be associated with the machine operation of mapping the current configuration state of the system to a new configuration state. The time defined in this sense need not be that associated with the physical time. Moreover, the objects and the lattice of a dynamical system need not be assumed to be directly related to physical objects in physical space. In this way we may consider models of dynamical systems where the notions of physical objects along with physical spacetime are emergent.
2.5 Programs.
Programs are made up of strings or lists of strings with a well defined structure and are assigned the type denoted by . Program names are assigned the type and are subtypes of alphanumeric strings, i.e. .
We start by defining an atomic program.
Definition 2.5.1.
(Atomic program.) An atomic program has the representation
with the allocation of types of its component parts given by
The program name and the lists and are separated by a space and the expression is treated as a single string of type . An atomic program satisfies all of the following conditions.

Elements of the I/O lists
are alphanumeric variable names (type ) that serve as placeholders for assigned values. The output list, , may be the empty list.

The type of the assigned value of every element of the I/O lists is checked within the program. If there is a type violation of any value assigned element then the program halts with an error message

The variable names of the elements of the output list, , are distinct, i.e.

No element of the input list, , can have a variable name that coincides with a variable name of an element of the output list, , i.e.
Programs are constructed from lists of atomic programs. Both atomic programs and program lists have the generic type . An atomic program can be distinguished from a program list by the subtype .
Definition 2.5.2.
(Program list.) A program can be represented by a list
(2.5.1) 
for some , where each triplet , , is an atomic program so that and . The I/O lists, and , of the atomic programs, , , have the expanded form
(2.5.2)  
The atomic programs, , , are referred to as subprograms of the program list. The program list, (2.5.1), satisfies all of the following conditions.

The variable names of the elements of the subprogram output lists are distinct, i.e.

For each , the variable names of the elements of the list must not coincide with a variable name of the elements of the lists for , i.e.
We write
to indicate that is a program with list length . The parameter dependent type is a subtype of the generic type , i.e. .
Matrix representations of programs. Both atomic programs and program lists have the generic type . The same notation, , for program lists, (2.5.1), is used and can be thought of having the matrix representation
(2.5.3) 
where we have defined
maximum length of the input lists of all atomic programs  
maximum length of the output lists of all atomic programs 
Blanks are inserted for elements of the arrays and that do not contain variables. Here can be thought of in terms of the traditional transpose of a vector that is a vertical list of the atomic program names of its subprograms. From the perspective of machine memory a vertical list is indistinguishable from a horizontal list so that we can simply write . The I/O lists are also arrays with
The notation defines the type program list of length that can be expressed as both (2.5.1) and (2.5.3).
Often we shall simply represent a program as a vertical list
(2.5.4) 
It is important to note throughout that when dealing with program lists each and , , are themselves lists.
The execution of the program (2.5.4), for a given value assigned input, is completed when all of the subprograms, , , have been executed in the sequential order from top to bottom in the vertical program list.
For we simply drop the list representation so that represents an atomic program. We may also write . The case means that the program is the empty program list, denoted by or the alphanumeric name .
I/O value assignments. The elements of the I/O lists of a program, , are alphanumeric strings that serve as placeholders for assigned values. The action of assigning a value to an alphanumeric string that represents an element of an I/O list involves the allocation of an address where the assigned value of the alphanumeric string and its type are stored. These assigned values can be integers, fixed precision rational numbers or other objects of a well defined type.
An element of an I/O list may also be assigned a value that comes in the form of a list or an array. In such a case it is understood that the the assigned value is a subtype of of a specified length.
Constants. We need to make a distinction between common variables and constants. For each type there may exist special objects of that type that appear as fixed assigned values in an input list of a program.
Throughout we use the notation
(2.5.5) 
to denote the list of variable names used as elements of I/O lists that are distinguished from the names of constants that are elements of the list
(2.5.6) 
Each element, , of the list of constants, , is an alphanumeric string that is assigned a fixed value. The fixed value assignments of the elements of need not be of the same type.
I/O dependency condition. Input variable names of a program may be elements of and/or while output variable names can only be elements of . When an atomic program is placed in a program list it can have an input variable name that coincides with an I/O variable name of a subprogram that precedes it in the program list. Such an input variable is said to be a bound variable. An input variable may also be bound to a constant. An input variable that is not bound is said to be a free variable. All elements of program output lists can be considered as free variables.
We distinguish between different kinds of variable bindings for program lists. For a program , , the I/O lists have the expanded form
(2.5.7)  
The possible variable bindings are as follows.

Input variable bound to a constant.
(2.5.8) 
Input variable bound to another input variable within a subprogram.
(2.5.9) 
Input variable bound to an input variable of a preceding subprogram.
(2.5.10) 
Input variable bound to an output variable of a preceding subprogram.
(2.5.11)
The sequential order of subprograms that are not subject to the bound variables of the kind (2.5.11) can be interchanged in a program list. The sequential order of subprograms that are subject to the bound variables of the kind (2.5.11) cannot be interchanged. We shall often refer to this property as the I/O dependency condition. The I/O dependency condition is a consequence of our functional program list representation that disallows reassigning values to a variable name. This differs from imperative programming languages where it is common to reassign values to a variable name within a program. The I/O dependency condition plays a crucial role on how program lists can be manipulated.
The list of primary input variables for a program list , , is defined by
(2.5.12) 
that lists all of the input variable names that are not bound to output variables. The unique function is used to remove repetitions. We will always discuss the computability of programs with respect to the value assignments of their primary input variables.
The list of free variables names of the input list of the program list , is defined by
(2.5.13) 
The variable name of each element of the output list of a program is unique. The elements of the list
(2.5.14) 
can be regarded as output variables that are employed as intermediate calculations in a program list. Output variables that are elements of the list
(2.5.15) 
can be thought of as the primary output variables of the program. Programs written in some imperative language often discard variables that are employed in intermediate calculations returning only the primary output variables. In our functional program format such variables are not discarded.
The read/print programs. A program list (2.5.4) should be thought of as being a core program embedded in a larger program that can be represented by the vertical list
(2.5.16) 
The variable name is associated with a file where the value and type assignments of each element of is stored. It can be assumed that all elements of are assigned their values and types in an initializing file that can be accessed by a program whenever a constant variable is encountered in a subprogram input list.
The variable name is associated with a file where the output, , is written. By accessing an input data file, , the program
assigns to each element of the unbound variables of the input list a value and a type consistent with the entry type checking of the subprograms of the program (2.5.4). The assigned values and types of the elements of the output list, , are generated through the dual actions of value and type assignments contained within the subprograms of the program.
The program
prints the value assigned output list, , to a file, . If an execution error is encountered in the program the execution is halted and an error message is printed to a file and/or screen. For the purposes of analysis the core program, , will always be considered in isolation with the understanding that the value and type assignments of the elements of the free input list, , have been prescribed by the initializing program .
Elements of program lists. It is convenient to rewrite (2.5.3) as an augmented matrix
In this form each row, , can be regarded as an element of the program represented as a vertical list.
A program list represented by (2.5.1) is a list of ordered triplets
We will always define individual elements of a program list to be the strings of triplets , , that represent the subprograms of . We write
to mean that the triplet is an individual element of the program list . The notion of a sublist of a program is defined in terms of the elements of a program list in this sense.
When reading a program represented as a vertical list the machine will recognize each subprogram, defined by the triplet , as an individual string so that the internal spaces that separate the program name and the I/O lists will be regarded as special characters of that string. Each triplet has a well defined structure so that the machine will have no trouble in recognizing the internal spaces that separate the components of the triplet as special characters of the string that represents an atomic program.
Notes.

If the empty program is encountered in the execution of a program list then the program does not halt and execution proceeds to the next subprogram of the list. Subprograms of a program list that are empty programs can be immediately removed by the process of an empty list extraction.

Haskell is a common functional programming language that is employed in the computer sciences. It exploits the lambda calculus formulation and can be employed as a proof checker using the inference rules of propositional and first order logic. An introductory coverage of Haskell can be found in [32].

At this point, a reader who has a background in the computer sciences might regard the I/O dependency condition as an unnecessary complication that is bypassed in the lambda calculus. It can only be recommended here that the reader persevere. An attempt will be made to demonstrate that the I/O dependency condition is quite manageable and that our language will contain some useful features for the purposes that it is has been designed.
2.6 Computability.
Execution error. Within all programs type checking is performed on the assigned values of all elements of the I/O lists. Execution errors are based on type violations. A program will halt with an execution error if during its execution there is a type violation of any assigned value of the elements of its I/O lists. Otherwise, the execution of a program is completed when all subprograms of the program list have been successfully executed in the sequential order that they appear in the list.
In the next section we will introduce atomic programs that also check for the satisfaction of a relation between a pair of elements of its input list. In such cases an execution error will also include the case where the relation is not satisfied.
In a later chapter we will also introduce program disjunctions. Disjunctions essentially split the execution of a single program list into a number of parallel program lists. These parallel program lists can be associated with operands of the disjunction. If at least one of the operand programs of the disjunction does not contain a type violation then all type violations that exist in the other operand programs are overridden and the main program will not halt with an execution error.
A more formal definition of an execution error will be postponed until we have introduced disjunctions. For the moment it will suffice to regard an execution error to be solely associated with the encounter of a type violation in a single program list.
Computable programs. Our main objective is to construct computer models that can be validated by establishing computability. By this it is meant that a program will eventually halt without encountering an execution error and return a value assigned output.
In general there may exist programs for which we will be unable to rigorously establish computability or noncomputability for that matter. In the computer sciences undecidability is highlighted by the the halting problem, although this is almost exclusively discussed in the context of abstract computers such as Turing machines with infinite tapes. Undecidability also arises in mathematics where it is often regarded as troublesome and a reminder of a limitation of mathematics. In a more general context of the scientific method, undecidability is an accepted concession where the best that can be hoped for is a process of continual revision from which will emerge theories with expanded scope of applicability. These issues will be addressed in more detail in the final chapter of this book. With these issues in mind the following definition of computability will be sufficient for the most part.
Definition 2.6.1.
(Computability.) A program is said to be computable, with respect to the value assignments of its primary input variables, , if upon execution it eventually halts without encountering an execution error based on type violations. A computable program returns the value assigned output, , where may be the empty list.
Terms and assignment maps. Programs can have an empty output list. Programs with an empty output list are often associated with the sole task of checking the types of the value assignments of the elements of their input list.
An atomic program, , with a nonempty output list, , will be referred to as a value assignment program to be distinguished from a type assignment program. Where there is no confusion in the context we refer to value assignment programs as simply assignment programs.
Assignment programs are often associated with arithmetic calculations but may also involve algorithms that cannot be concisely expressed in the conventional mathematical notation. The internal algorithm of an atomic program can be thought of as a sequence of instructions, including arithmetic computations, written in some imperative language.
We introduce the type . Objects of type are alphanumeric character strings that also include the special characters . Terms take the general form
Terms will often be used to represent functions. We have already used terms to express the functions , , and . We have also used terms to express parameter dependent types where the term name is given in bold characters.
Given a list the expression
means that is assigned the values assigned to the elements of through a function or map . The object
can be associated with the classical function notation . Note that spaces are used instead of commas to separate the arguments of the the term.
For a value assignment program, , the term notation
is used to indicate that the program can be associated with the map , where for convenience the name of the term is the same as the associated program name. We will often refer to the expression as the assignment map of the value assignment program . If it will be understood that represents a list of terms of length . Sometimes we will just represent the assignment map of a program, , by to indicate a map from objects of type to objects of type . While the association of programs with maps and functions will be useful it should not be taken too formally since our approach will be mainly syntactic based on the manipulation of strings.
In Chapter 9 we consider programs where the assigned values of the output list are character strings of type . This will be useful in applications of VPC where higher levels of abstractions are employed. Abstract objects are assigned abstract types that can represent maps from sets to sets or predicates of sets.
False programs. In the context of value assignment programs, the associated function can be thought of as a partial function. There are cases where an object has all of the structural properties of a program but will not be computable for any type compatible valued input list.
Definition 2.6.2.
(False program.) A program is said to be a false program if there does not exist a value assigned input list such that the program is computable. A false program is assigned the type , where .
In the definition of a false program it is stated that . This means that for an object to have the type assignment it must first have the structure of a program under Definitions 2.5.1 and 2.5.2. The statement that a program will always halt as a result of an error in syntax is not considered meaningful in this context since such an object cannot be assigned the type .
2.7 Atomic programs.
Programs are built up from lists of atomic programs. The internal algorithms of atomic programs will be understood to be constructed from some imperative language and is not seen by the machine during constructions of program lists. Because the internal algorithm of an atomic program is not accessible to the machine in explicit form it will be necessary to supply a collection of rules or axioms that describe it. It is through these axioms that the machine will be able to recognize the main computational operations associated with the internal algorithm of an atomic program.
Definition 2.7.1.
(Atomic program.) An atomic program is a subtype of program type, . An atomic program must include type checking for the assigned values of every element of its I/O lists. If for any value assigned element of the I/O lists, and , there is a type violation the program halts prematurely as a type violation error. Otherwise the atomic program returns the assigned valued output, , where may be the empty list. Atomic programs may call other atomic programs but each atomic program introduces a new computational operation.
Atomic programs can be partitioned into the three subtypes of type and relation checking, value assignment and type assignment.
Definition 2.7.2.
(Type checking programs.) A type checking program, , is an atomic program with the following properties.

The output list is the empty list so that type checking programs have the representation .

The type of the assigned values of every element of the input list is checked upon entry.

If a type violation is encountered the program halts prematurely with a type violation error.
A type checking program is assigned the type , where .
Type checking within a program is an action that checks the type of the assigned value of a given variable. Type checking may also include the checking of some relation between its input variables. For example, type checking for valued assigned variables that are integers, say and , may include a check for value assigned equality, , or value assigned inequality, . In other words a type violation error will include failure of at least one of the actions of type checking, , , and the value assigned equality or inequality.
Definition 2.7.3.
(Value assignment programs.) Value assignment programs are atomic programs that combine all of the actions of entry type checking, value assignment and type assignment. A value assignment program, , has the following properties.

The type of the assigned values of every element of the input list, , is checked upon entry.

If there is a type violation of at least one element of the input list the program halts prematurely with a type violation error.

If, upon entry, there are no type violations, a value assignment program then attempts to assign a value to each element of the output list through the action of an assignment map.

If there is a type violation of an assigned value of an element of the output list the program halts with a type violation error.

If there are no type violations each element of the output list, , is assigned a value and a type consistent with the value assignment.
A value assignment program has the type , where .
Object has type is denoted by . Throughout we will use the notation
to denote the action of assigning object the type .
Abstract types. There will be situations where objects of some specific type will be assigned a new type. These newly assigned types will often be referred to as abstract types.
Definition 2.7.4.
(Type assignment programs.) A type assignment program, , is an atomic program with the following properties.

Type assignment programs do not introduce new variables nor do they modify the assigned values of the input variables. They admit input objects that have already been assigned a value with a well defined type. Hence type assignment programs have an empty output list, , with the representation .

The input list will contain an object that is the target of the new type assignment. The input list may also include additional objects that serve as parameters on which the new subtype is dependent on.

The type of the assigned values of every element of the input list is checked upon entry. The check is performed on the type already assigned to each input variable upon entry and not the type that is to be assigned.

If there is a type violation the program halts prematurely with a type violation error.

If, upon entry, there are no type violations, a type assignment program then assigns to the target element of the input list a new type.

Once the target variable is assigned the new type it is internally stored in memory as such so that if the target variable is encountered as input in a subprogram of a larger program list it is identified by that assigned type.
A type assignment program has the type , where .
For each atomic abstract type assignment program, type , there must be an associated type checking program, type . The important distinction between programs of type and programs of type is that the latter create new variables and assign a value to these variables. Type programs do not create new variables and do not modify the values assigned to the existing variables that appear in their input list. The properties of objects associated with abstract types can only be recognized by the machine through a supplied collection of axioms.
Pseudoatomic programs. Sometimes it might be convenient to define a program as atomic even though it could otherwise be represented as a program list. Such programs are said to be pseudoatomic programs.
Consider the program list
(2.7.1) 
where, as usual, and are lists and we write
Let
be defined as the pseudoatomic program of the program list (2.7.1). The input list, , of the pseudoatomic program, , is given by
where is the list of constants, and the output list, , is given by
We see that the input list, , of the pseudoatomic program, , removes all constants and input variable names associated with intermediate calculations in the program list (2.7.1). Repetitions of variable names are removed by the function. The output list, , of the pseudoatomic program, , removes all output variable names that are employed as intermediate calculations of the program list, (2.7.1), retaining only the primary output variable names.
While the internal algorithm of the pseudoatomic program, , is based on a program list of atomic programs, the actual program list (2.7.1) is not seen by the machine. As with standard atomic programs, because the internal algorithm of a pseudoatomic program is not accessible to the machine in explicit form it will be necessary to supply a collection of rules or axioms that describe it.
For pseudoatomic programs associated with long program lists the collection of rules or axioms that need to be supplied might be very large. The convenience of defining a pseudoatomic has to be weighed against the number of rules that have to accompany it.
Notes.

All programs will be constructed from atomic programs through the construction rules to be presented in the following chapters. Hence all programs will contain the action of type checking for the assigned values of all elements of their I/O lists.

Due to the I/O dependency condition there is no general rule that allows the repetition of subprograms of a program list. However, repetition of subprograms with an empty list output is allowed and will not effect the computability of the program list. For computational efficiency such repeated subprograms are redundant and should be avoided.
3.1 Introduction.
Our objective is to construct a formal language from which we can determine the computability of programs, with particular interest in programs that are designed to model fully discrete dynamical systems. Adopting a language based on programs under the constraints of a machine environment, , will require a departure from conventional languages employed in formal systems of proof theory. Here we will lay down a collection of program construction rules that better reflect the operational constraints of our language based on programs on a working platform .
To this end we will largely deal with objects that are recognized by the machine from their string structure. These include subtypes of strings or lists of strings such as machine integer scalars and vectors and programs. As a result we will be dealing with a low level language that will lack the expressiveness found in many formal systems of proof theory. However, we will demand that the language possess the power of analysis at a sufficiently high level. We will also demand that the language be soundly rooted as a primitive on top of which theories requiring higher levels of abstractions can be built.
The construction rules form the basis of the program VPC and can be regarded as the general inference rules that are
Comments
There are no comments yet.