The semantic foundation of the UTP is the first-order predicate calculus, augmented with fixed point constructs from second-order logic. Following the tradition of Eric Hehner, programs are predicates in the UTP, and there is no distinction between programs and specifications at the semantic level. In the words of Hoare:
A computer program is identified with the strongest predicate describing every relevant observation that can be made of the behaviour of a computer executing that program.2
In UTP parlance, a theory is a model of a particular programming paradigm. A UTP theory is composed of three ingredients:
Program refinement is an important concept in the UTP. A program P 1 {\displaystyle P_{1}} is refined by P 2 {\displaystyle P_{2}} if and only if every observation that can be made of P 2 {\displaystyle P_{2}} is also an observation of P 1 {\displaystyle P_{1}} . The definition of refinement is common across UTP theories:
P 1 ⊑ P 2 if and only if [ P 2 ⇒ P 1 ] {\displaystyle P_{1}\sqsubseteq P_{2}\quad {\text{if and only if}}\quad \left[P_{2}\Rightarrow P_{1}\right]}
where [ X ] {\displaystyle \left[X\right]} denotes3 the universal closure of all variables in the alphabet.
The most basic UTP theory is the alphabetised predicate calculus, which has no alphabet restrictions or healthiness conditions. The theory of relations is slightly more specialised, since a relation's alphabet may consist of only:
Some common language constructs can be defined in the theory of relations as follows:
s k i p ≡ v ′ = v {\displaystyle \mathbf {skip} \equiv v'=v}
a := E ≡ a ′ = E ∧ u ′ = u {\displaystyle a:=E\equiv a'=E\land u'=u}
P 1 ; P 2 ≡ ∃ v 0 ∙ P 1 [ v 0 / v ′ ] ∧ P 2 [ v 0 / v ] {\displaystyle P_{1};P_{2}\equiv \exists v_{0}\bullet P_{1}[v_{0}/v']\land P_{2}[v_{0}/v]}
P 1 ⊓ P 2 ≡ P 1 ∨ P 2 {\displaystyle P_{1}\sqcap P_{2}\equiv P_{1}\lor P_{2}}
P 1 ◃ C ▹ P 2 ≡ ( C ∧ P 1 ) ∨ ( ¬ C ∧ P 2 ) {\displaystyle P_{1}\triangleleft C\triangleright P_{2}\equiv (C\land P_{1})\lor (\lnot C\land P_{2})}
μ X ∙ F ( X ) ≡ ⊓ { X ∣ F ( X ) ⊑ X } {\displaystyle \mu X\bullet \mathbf {F} (X)\equiv \sqcap \left\{X\mid \mathbf {F} (X)\sqsubseteq X\right\}}
Hoare, C. A. R.; Jifeng, He (April 1, 1998). Unifying Theories of Programming. Prentice Hall. p. 320. ISBN 978-0-13-458761-5. Retrieved 17 September 2014. 978-0-13-458761-5 ↩
Hoare, C.A.R. (April 1984). "Programming: Sorcery or science?". IEEE Software. 1 (2): 5–16. doi:10.1109/MS.1984.234042. S2CID 375578. /wiki/IEEE_Software ↩
Dijkstra, Edsger W.; Scholten, Carel S. (1990). Predicate calculus and program semantics. Texts and Monographs in Computer Science. Springer. ISBN 0-387-96957-8. 0-387-96957-8 ↩