{'fraction_non_alphanumeric': 0.041028063876027594, 'fraction_numerical': 0.007880563167343854, 'mean_word_length': 4.594840346796363, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 1, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
NOOP: A Domain-Theoretic Model of Nominally-Typed OOP

The majority of industrial-strength object-oriented (OO) software is written using nominally-typed OO programming languages. Extant domain-theoretic models of OOP developed to analyze OO type systems miss, however, a crucial feature of these mainstream OO languages: nominality. This paper presents the construction of NOOP as the first domain-theoretic model of OOP that includes full class/type names information found in nominally-typed OOP. Inclusion of nominal information in objects of NOOP and asserting that type inheritance in statically-typed OO programming languages is an inherently nominal notion allow readily proving that type inheritance and subtyping are completely identified in these languages. This conclusion is in full agreement with intuitions of developers and language designers of these OO languages, and contrary to the belief that"inheritance is not subtyping,"which came from assuming non-nominal (a.k.a., structural) models of OOP. To motivate the construction of NOOP, this paper briefly presents the benefits of nominal-typing to mainstream OO developers and OO language designers, as compared to structural-typing. After presenting NOOP, the paper further briefly compares NOOP to the most widely known domain-theoretic models of OOP. Leveraging the development of NOOP, the comparisons presented in this paper provide clear, brief and precise technical and mathematical accounts for the relation between nominal and structural OO type systems. NOOP, thus, provides a firmer semantic foundation for analyzing and progressing nominally-typed OO programming languages.


Introduction
To evolve and improve the type systems of mainstream object-oriented programming languages such as Java (Gosling et al., 2014), C# (2015), C++ (2011), andScala (Odersky, 2014), which utilize class name information in defining object types and OO subtyping, a precise mathematical model of these languages is needed. A precise model of nominally-typed OOP allows accurate reasoning and analysis of these mainstream OO programming languages. Imprecise models, on the other hand, lead to inaccurate conclusions.
An object in nominally-typed OO languages is associated with its class 1 name and the class names of its superclasses, as part of the meaning of the object. Class names, in turn, are associated with class contracts, which are usually expressed, informally, in code documentation. Class contracts are thus implicitly encoded in class names.
In nominally-typed OOP, two objects with the same structure but that have different class name information are different objects, and they have different types. The different class name information inside the two objects implies the two objects maintain different class contracts, and thus that the objects are behaviorally dissimilar. The two objects are thus considered semantically unequal. Further, in nominally-typed OO languages-where types and the subtyping relation make use of class names and of the explicitly-specified type inheritance relation between classes-instances of two classes that are not in the inheritance hierarchy may not be replaced by each other (i.e., are not 'assignment-compatible') since they may not offer the degree of behavioral substitutability intended by developers of the two classes.
Despite its clear semantic importance, class name information (henceforth, 'nominal information') that is embedded inside objects of many mainstream OO programming languages is not included in the most recognized denotational models of OOP that exist today. Models of OOP that lack nominal information of mainstream OO languages are structural models of OOP, not nominal ones. Examples of structurally-typed OO languages include O'Caml (Leroy et al., n.d.) (see (Mac-Queen, 2002)) and research languages such as Modula-3 (Cardelli et al., 1989), Moby (Fisher & Reppy, 1999), Strongtalk (Bracha & Griswold, 1993), and Poly-TOIL (Bruce et al., 2003). Structural models of OOP have led PL researchers to make some conclusions about OOP that contradict the intuitions of the majority of mainstream OO developers and language designers. For example, the agreement of type inheritance, at the syntactic (i.e., program code) level, and subtyping, at the semantic (i.e., program meaning) level, is a fundamental intuition of OO developers using nominally-typed OO languages. However, extant denotational models of OOP led to the inaccurate conclusion that "inheritance is not subtyping." Type inheritance, in class-based mainstream OO languages, is an inherently nominal notion, due to the informal association of class names with inherited class contracts. Hence the discrepancy between conclusions regarding inheritance that are based on a structural view of OOP and the intuitions of the majority of mainstream OO developers, who adopt a nominal view of OOP. This discrepancy motivated considering the inclusion of nominal information in mathematical models of OOP.
1 The term 'type' is overloaded. In this paper, the term has mainly two related but distinct meanings. The first meaning, mainly used by OO software developers, is a syntactic one, that directly translates to the expression 'class, interface, or trait' (in OO programming languages that support these constructs). In this sense, each class, interface, or trait is a type. The second meaning for 'type,' mainly used by mathematicians and programming languages researchers, is a semantic meaning referring to the set of instances of a corresponding class/interface/trait. In this sense, each class, interface, or trait corresponds to a type. Usually the context makes clear which sense of the two is meant, but, to emphasize, sometimes we use the term 'class' for the syntactic meaning. As such, unless otherwise noted the term 'class' in this paper should be translated in the mind of the reader to 'class, interface or trait.' This paper presents the construction of a mathematical model of OOP, called NOOP, that includes full nominal information of mainstream OO programming languages. NOOP was first presented in (AbdelGawad, 2012) and its construction was summarized in (AbdelGawad, 2014a).
Having a model of OOP that includes nominal information of nominally-typed OOP should enable progress in the design of type systems of current and future mainstream OO languages. Some features of the type systems of these languages (e.g., generics) crucially depend on nominal information. Accurately understanding and analyzing these features, for the purposes of extending the languages or designing new languages that include them, has proven to be hard when using operational models of OOP or using structural denotational models of OOP, which lack nominal information found in nominally-typed OO languages. Having a nominal domain-theoretic model of OOP should make the analysis of features of these languages that depend on nominal information easier and more accurate. From the point of view of OO software development, having better mainstream OO languages should result in greater productivity for software developers and in them producing robust high-quality software.
This paper is organized as follows. Section 2 presents a list of research related to this paper. Section 3 presents in brief the value of nominal typing to mainstream OO developers. Section 4 then starts the formal presentation of NOOP by presenting a new records domain constructor, called 'rec,' that is used in constructing NOOP. Section 5 presents class signatures and other related signature constructs, which are syntactic constructs used to embody the nominal information found in nominallytyped OOP. Section 6 presents the construction of NOOP, using 'rec' and signature constructs, then it presents a proof of the identification of inheritance and subtyping in nominally-typed OOP. Section 7 then presents in brief a comparison of NOOP to the most well-known domain-theoretic models of OOP, namely the two structural models developed by Cardelli and by Cook. Section 8 presents the main conclusions we reached based on developing NOOP and on comparing it to other domaintheoretic models of OOP. Section 9 concludes this paper by presenting further research that can be developed based on NOOP.
Research on the semantics of OOP has taken place subsequently. Cardelli built the first widely known denotational model of OOP (Cardelli, 1984(Cardelli, , 1988a). Cardelli's work was pioneering, and naturally, given the research on modeling functional programming extant at that time, the model Cardelli constructed was a structural denotational model of OOP that lacked nominal information. 2 Cook and his colleagues built on Cardelli's work to separate the notions of inheritance 2 Significantly, Cardelli in fact also hinted at looking for investigating nominal typing (on page 2 of (Cardelli, 1988b)). Cardelli's hint, unfortunately, went largely ignored for years. and subtyping (Cook, 1989;Cook & Palsberg, 1989;Cook et al., 1990). Later, other researchers (such as (Bruce, 2002) and (Simons, 2002)) promoted Cardelli and Cook's structural view of OOP, and promoted conclusions based on this view.
Martin Abadi, with Luca Cardelli, later presented operational models of OOP (Abadi & Cardelli, 1994, 1996. These models also had a structural view of OOP. Operational models with a nominal view of OOP got later developed however. In their seminal work, Atsushi Igarashi, Benjamin Pierce, and Philip Wadler presented Featherweight Java (FJ) (Igarashi et al., 2001) as an operational model of a nominally-typed OO language. Even though not the first operational model of nominally-typed OOP (for example, see (Drossopoulou et al., 1999), (Nipkow & Von Oheimb, 1998) and (Flatt et al., 1998(Flatt et al., , 1999), FJ is the most widely-known operational model of (a tiny core subset of) a nominally-typed OO language, namely Java. 3 Other research that is similar to one presented here, but that had different research interests and goals, is that of Reus and Streicher (Reus, 2002;Reus & Streicher, 2002;Reus, 2003). In (Reus, 2003), an untyped denotational model of class-based OOP is developed. Type information is largely ignored in this work (object methods and fields have no type signatures) and some nominal information is included with objects only to analyze OO dynamic dispatch. The model of (Reus, 2003) was developed to analyze mutation and imperative features of OO languages and for developing specifications of OO software and the verification of its properties. Analyzing the differences between structurally-typed and nominally-typed OO type systems was not a goal of Reus and Streicher's research, and in their work the identification of inheritance and subtyping was, again (as in FJ), assumed rather than proven as a consequence of nominality and nominal typing.

The Value of Nominal-Typing in OOP
In this section we briefly present the value of nominal-typing and nominalsubtyping to OO software developers and OO language designers. More details on the value of nominal-typing and nominal-subtyping can be found in (AbdelGawad, 2016b).
As hinted to in the Introduction (Section 1), the main semantic value of nominaltyping to mainstream OOP lies in the association of type (i.e., class/interface/trait) names with behavioral contracts that are part of the public interface of objects, making typing and subtyping in nominally-typed OO languages closer to semantic typing and semantic subtyping than structural-typing and structural-subtyping are. Designing their software based on having public behavioral contracts allows OO developers to design robust software (Bloch, 2008).
The semantic value of nominal type information leads nominally-typed and structurally-typed OO languages to have different views of type names, where type names in nominally-typed OOP have fixed meanings (tied to the public contracts) while in structurally-typed OOP (in agreement with the tradition in functional programming) type names are viewed as mere 'shortcuts for type expressions' that can thus change their meanings, e.g., upon inheritance. This difference in viewing type names leads OO developers using structurally-typed OO languages to face 3 It is worthy to mention that NOOP-as a more foundational domain-theoretic model of nominally-typed OO languages (including Java)-provides a denotational justification for the inclusion of nominal information in Featherweight Java.
problems-such as spurious subtyping, missing subsumption, and spurious binary methods (see (AbdelGawad, 2016b))-that are not found in nominally-typed OO languages.
Further, the identification of type inheritance with OO subtyping ('inheritance is subtyping') resulting from nominal-typing (which we prove in this paper) enables nominally-typed OO languages to present OO developers with a simple conceptual model during the OO software design process.
Finally, due to the ubiquity of the need for objects in OOP to be "autognostic" (self-aware, i.e. recursive, see (Cook, 2009)) and given that recursive data values can be typed using recursive types (MacQueen et al., 1986), the ease by which recursive types can be expressed in nominally-typed OO languages is a decided benefit nominal-typing offers to OO software developers and designers (Pierce, 2002). More details on the benefits of nominal-typing can be found in (AbdelGawad, 2016b).
Without further ado, we now start the presentation of NOOP as a model of OOP that includes full nominal information found in many mainstream OO languages.

'Rec' (⊸), A New Records Domain Constructor
For the purpose of constructing NOOP, we introduce a new domain constructor. In addition to NOOP including nominal information of mainstream OOP, NOOP models records as tagged finite functions rather than infinite functions, as another improvement over extant domain-theoretic models of OOP (particularly that of Cardelli and other models built directly on top of it, such as Cook's.) Due to the finiteness of the shape of an object (the shape of an object is the set of names/labels of its fields and methods), and due to the flatness of the domain of labels when labels are formulated as members of a computational domain, modeling objects in NOOP motivates defining a new domain constructor that is similar to but somewhat different from conventional functional domain constructors. This domain constructor, ⊸, called 'rec,' constructs tagged finite functions, which we call record functions. Record functions are explicitly finite mathematical objects.
A domain R = L ⊸ D, constructed using ⊸, is the domain of record functions modeling records with labels from a flat domain L of labels to an arbitrary domain D of values. Below we present the records domain constructor, ⊸, then we discuss its mathematical properties. The definition of ⊸ makes use of standard definitions of basic domain theory (See, for example, (Cartwright et al., 2016). A summary of domain theory notions used to construct NOOP is presented in (AbdelGawad, 2014b) and in Appendix A of (AbdelGawad, 2012, 2013a).)

Record Functions.
A record can be viewed as a finite mapping from a set of labels (as member names) to fields or methods. Thus, we model records using explicitly finite record functions. A record function is a finite function paired with a tag representing the input domain of the function. The tag of a record function modeling a record represents the set of labels of the record. In agreement with the definition of shapes of objects, we similarly call the set of labels of a record the shape of the record. The tag of a record function thus tells the shape of the record. Let ⋐ denote the subdomain relation (see Definition 6.2 in (Cartwright et al., 2016).) If we let L f range over arbitrary finite subdomains of L (all subdomains L f contain ⊥ L ), then we define the domain R = L ⊸ D as the domain of record functions from L to D, where the universe, |R|, of domain R is defined by the equation and where tag is a function that maps the shape corresponding to a domain L f to a unique tag in a countable set of tags (whose exact format does not need to be specified), and where L f ⊸→ D is the standard domain of strict continuous functions from L f into D. Tags are needed in record functions to ensure that the records domain constructor is a continuous, in fact computable, domain constructor.
that models the empty record (one with an empty set of labels, for which The approximation ordering, ⊑ R , over elements of R is defined as follows. The bottom element ⊥ R approximates all elements of the domain R. Non-bottom elements r and r ′ in R with unequal tags are unrelated to one another. On the other hand, elements r and r ′ with the same tag are ordered by their embedded functions (which must be elements of the same domain.) Formally, for two non-bottom record functions r, r ′ in R that are defined over the same Having defined the records domain constructor ⊸, we now discuss its mathematical properties. Because in the construction of NOOP we use ⊸ to construct domains as least fixed points of functions over domains, where the constructed domains need to be subdomains of Scott's universal domain, U, we need to ascertain that ⊸ has the domain-theoretic properties needed for it to be used inside these functions. We thus need to prove that ⊸ is a continuous function over its input domain D, i.e., that, as a function over domains, ⊸ is monotonic with respect to the subdomain relation, ⋐, and that ⊸ preserves least upper bounds of domains under that relation. Proof. See Appendix B.

Class Signatures
In this section we present formal definitions for class signatures and related constructs. Class signatures and other signature constructs are syntactic constructs that capture nominal information found in objects of mainstream OO software. Embedding class signature closures (formally defined below) in objects of NOOP makes them nominal objects, thereby making NOOP objects more precise models of objects in mainstream OO languages such as Java, C#, C++, and Scala.
Class signatures formalize the notion of object interfaces. A class signature corresponding to a class in nominally-typed mainstream OOP is a concrete expression the interface of the class, i.e., of how instances of the class should be viewed and interacted with by other objects ("the outside world"). 4 To capture nominal information of nominally-typed mainstream OOP, we define three syntactic signature constructs: (1) class signatures, (2) class signature environments, and (3) class signature closures. Additionally, fields and methods, respectively, have (4) field signatures and (5) method signatures.

Class Signatures.
If N is the set of all class names, and L is the set of all member (i.e., field and method) names, we define a set S that includes all class signatures by the equation where × and * are the cross-product and finite-sequences set constructors, respectively, FS = L × N is the set of field signatures, and MS = L × N * × N is the set of method signatures. The equation for S expresses that a class signature corresponding to a certain class is composed of four components: (1) The class name (also used as a signature name for the class signature), (2) A finite sequence of names of immediate supersignatures of the signature, i.e., of signatures corresponding to immediate superclasses of the class, (3) A finite sequence of field signatures corresponding to class fields, and (4) A finite sequence of method signatures corresponding to class methods. The use of signature names (members of N) inside signatures characterizes class signatures as nominal constructs, where two signatures with different names but that are otherwise equal are different signatures.
The second component of a signature, a (possibly empty) sequence of signature names (i.e., a member of N * ), is the immediate supersignature names component of the class signature. Having names of immediate supersignatures of a class signature explicitly included as a component of the class signature is an essential and critical feature in the modeling of nominal subtyping in nominally-typed OOP. Explicitly specifying the supersignatures of a class signature identifies the nominal structure of the class hierarchy immediately above the named class. This also agrees with the inheritance of the contract associated with class names, which is a crucial semantic component of what is intended to be inherited in nominally-typed mainstream OOP.
The equation for field signatures expresses that a field signature is a pair of a field name (a member of L) and a class signature name. Similarly, the equation for method signatures expresses that a method signature is a triple of a method name, a sequence of class signature names (for the method parameters), and a signature name (for the method result).
Not all members of set S are class signatures. To agree with our intuitions about describing the interfaces of classes and their instances, a member s of S is a class signature if its supersignature names component, its field signatures component and its method signatures component (i.e., the second, third and fourth components of s) have no duplicate signature names, field names, and method names, respectively (For simplicity, method overloading is not modeled in our model of OOP.) It should be noted, however, that field names and method names are in separate name spaces and thus we allow a field and a method to have the same name.
Information in class signatures is derived from the text of classes of OO programs. Given that interfaces of objects are the basis for defining types in OO type systems, class signatures are the formal basis for nominally-typed OO type systems, so as to confirm that objects are used consistently and properly within a program ((AbdelGawad, 2016b), Ch. 2 of (AbdelGawad, 2013a), and (AbdelGawad, 2013b), give more details on types and typing in OOP.)

Signature Environments.
A signature environment is a finite set of class signatures that has unique class names, where each signature name is associated with exactly one class signature in the environment. (Accordingly, function application notation can be used to refer to particular class signatures in a signature environment. If nm is a signature name guaranteed to be the name of some class signature in a signature environment se, we use function application notation, se(nm), to refer to this particular class signature.) In addition to requiring the uniqueness of signature names, a finite set of class signatures needs to satisfy certain consistency conditions to function as a signature environment. A signature environment specifies two relations between signature names: an immediate supersignature relation and a direct-reference (adjacency) relation (The first relation is a subset of the second.) These two relations can be represented as directed graphs. The consistency conditions on a signature environment constrain these two relations and their corresponding graphs.
As such, a finite set se of class signatures is a signature environment if and only if (i) A class signature, with the right signature name, belongs to se for each signature reference in each class signature of se, (ii) The graph for the supersignatures relation for se is an acyclic graph (This constraint forces any signature environment to have at least one class signature that has no supersignatures, i.e., its second component is the empty sequence), and (iii) The set of field signatures and method signatures of each class signature s in se is a superset of the set of field signatures and method signatures of each supersignature named by the supersignatures component of s.
In agreement with inheritance in mainstream OO languages, the last condition makes class signatures in signature environments reflect the explicit inheritance information in class-based OOP, by requiring a class signature to only extend (i.e., add to) the set of members supported by an explicitly-specified supersignature. Requiring the members of a class signature to be a superset of the members of all of its supersignatures means that exact matching of member signatures is required. This requirement thus enforces an invariant subtyping rule for field and method signatures, mimicking the rule used in mainstream OO languages (such as Java and C#) before the addition of generics. This condition can be relaxed but we do not do so in this paper. More details are available in (AbdelGawad, 2012). 5.3. Signature Closures. Inside a class signature, class names can be viewed as "pointers" that refer to other class signatures. Without bindings of class names to corresponding class signatures, a single class signature that has name references to other class signatures is not a closed entity on its own. This motivates the notion of a signature closure. A closure of a class signature is a set of class signatures (a signature environment, in particular) that offers bindings to class names referred to in all elements of the set, such that the whole set has no "dangling pointers" in its references to other class signatures (i.e., is referentially-closed) and has no redundant class signatures relative to some main class signature in the set (called the root class signature of the closure.) A signature closure thus "closes" the root class signature by providing bindings for all class names referenced, directly or indirectly, in the signature. This motivates the following formal definition of signature closures.
A signature closure is a pair of a signature name and a signature environment. A pair sc = (nm, se) of a signature name nm and a signature environment se is a signature closure if and only if there exists a class signature s in se with signature name nm and if the direct-reference (adjacency) relation corresponding to se is referentially-closed relative to s, and if this relation is the smallest such relation. Class signature s is then called the root class signature of sc. Relative to the root class signature, a signature environment is minimal, i.e., contains no unnecessary class signatures. This minimality condition ensures that all class signatures in the signature environment of a signature closure are accessible via paths in the adjacency graph of the signature environment starting from (the node in the graph corresponding to) the root signature name, i.e., that the signature environment has no redundant class signatures unnecessary for the root class signature.
Similar to a single class signature, when viewed as a "closed class signature" a signature closure has a name: namely, that of its root class signature; has member signatures: namely, field and method signatures of its root class signature; has a fields shape and a methods shape: namely, those of its root class signature; and it has immediate supersignature names: namely, those of its root class signature. A signature closure, not just a class signature, is the full formal expression of the notion of object interfaces. Each class in a class-based OOP program has a corresponding class signature and a corresponding class signature closure. The nominal information in a class signature closure is an invariant of all instances of the class (including the behavioral contracts associated with class names.)
Finally, a relation between signature environments that is needed when we discuss inheritance is the extension relation on signature environments. A signature environment se 2 extends a signature environment se 1 (written se 2 ◭ se 1 ) if se 2 binds the names defined in se 1 to exactly the same class signatures as se 1 does. Viewed as sets, se 2 is a superset of se 1 . Thus, 5.5. Subsigning and Inheritance. The supersignatures component of class signatures defines an ordering relation between signature closures. We call this relation between signature closures subsigning. The subsigning relation between class signature closures models the inheritance relation between classes in class-based OOP.
A signature closure sc 2 = (nm 2 , se 2 ) is an immediate subsignature ( 1 ) of a signature closure sc 1 = (nm 1 , se 1 ) if the signature environment (i.e., the second component) of sc 2 is an extension (◭) of the signature environment of sc 1 and the signature name of sc 1 is a member of the supersignature names component of the root class signature of sc 2 , i.e., sc 2 1 sc 1 ⇔ se 2 ◭ se 1 ∧ (nm 1 ∈ super_sigs(se 2 (nm 2 ))).
The subsigning relation, , between signature closures is the reflexive transitive closure of the immediate subsigning relation ( 1 ). To illustrate the definitions given in this section, Appendix A presents a few examples of signature constructs, and presents examples of signature closures that are in the subsigning relation.
The inclusion of class contracts in deciding the subsigning relation makes the subsigning relation a more accurate reflection of a true "is-a" (substitutability) relationship than the structural subtyping relation used in structurally-typed OOP. This makes subsigning capture the fact that subtyping in nominally-typed OOP is more semantically accurate than structural subtyping, as mentioned earlier, and as is explained in more detail in (AbdelGawad, 2016b).

NOOP: A Model of Nominal OOP
Using the records domain constructor (⊸) presented in Section 4 and signature constructs presented in Section 5, in this section we now present the construction of NOOP as a more precise model of nominally-typed mainstream OOP.
The construction of NOOP proceeds in two steps. First, the solution of a simple recursive domain equation defines a preliminary domainÔ of raw objects, where an object inÔ contains (1) a signature closure that encodes nominal information of nominally-typed OOP, and contains bindings for object members in two separate records: (2) a record for fields of the object, and (3) a record for methods of the object.
A simple recursive definition of objects with signature information does not force signature information embedded in objects to conform with their member bindings. Accordingly, in the second step of the construction of NOOP, invalid objects in the constructed preliminary domain of objectsÔ are "filtered out" producing a domain O of proper objects that model nominal objects of mainstream OO software. Invalid objects are ones where the signature information is inconsistent with member bindings in the member records. The filtering of the preliminary domain is done by defining a projection function on the preliminary domainÔ.
We call the model having the preliminary domain defined by the domain equation 'preNOOP'. Our target model, NOOP, is the one containing the image domain resulting from applying the filtering function on the preliminary domainÔ of preNOOP. The domain equation that describes preNOOP is where the main domain defined by the equation,Ô, is the domain of raw objects, × is the strict product domain constructor, and ⊸ is the records domain constructor (Section 4). Equation (4) states that every raw object (i.e., every element inÔ) is a triple of: (1) A signature closure (i.e., a member of S), DomainÔ of preNOOP is the solution of Equation (4). Applying the iterative least-fixed point (LFP) construction method from domain theory (Cartwright et al., 2016), the construction ofÔ proceeds in iterations, driven by the structure of the right-hand side (RHS) of Equation (4). The RHS of the equation is viewed as a continuous function over domains (given the continuity of all used domain constructors, and that constructor composition preserves continuity.) Details of the iterative construction of preNOOP are presented in (AbdelGawad, 2012). The second step in constructing NOOP is the definition of a projection/filtering function, filter, to map domainÔ of preNOOP to the NOOP domain O of valid objects modeling objects of nominally-typed OOP. For this, first, we define an object inÔ to be valid as follows.

Definition 6.1. An object o inÔ is valid if it is the bottom object ⊥ O , or if it is a non-bottom object o = (sc, f r, mr) such that
• The fields shape and the methods shape of sc are exactly the same as ( i.e., equal to) the shape of f r and the shape of mr, respectively, • Non-bottom valid objects bound to field names in f r have signature closures that subsign the signature closures for corresponding fields in sc, and • Non-bottom functions bound to method names in mr conform to corresponding method signatures in sc, where by conformance the functions are required to -take in sequences of valid objects whose embedded signature closures subsign (component-wise) the corresponding sequences of method parameter signature closures in sc, prepended with sc itself (for the implicit parameter self/this), and return valid objects with signature closures that subsign the corresponding return value signature closures specified in the method signatures in sc.
As a direct translation of Definition 6.1, the function filter mappingÔ intô O (O is a proper subdomain ofÔ) is defined using the following three recursive function definitions, presented using lazy functional language pseudo-code.
// nm is prepended to mi_snm j to handle 'this' let mosj = se_clos(se, mo_snm j ) return ((nm,se), (fr-tag, {a i → filter-obj-sig(si,o i ) | i=1,· · · ,m}), (mr-tag, {b j → filter-meth-sig(misj, mosj, m j ) | j=1,· · · ,n})) fun filter-obj-sig ( in filter-obj-sig(out_s, m(vos))) In the definition of filter, functions sf-shp and sm-shp compute field and method shapes of signatures, while function rec-shp computes shapes of records. Function se_clos(se,nm) computes a signature closure corresponding to signature name nm whose first component is nm and whose second component is the minimal subset of signature environment se that makes se_clos(se,nm) a signature closure. To handle this/self a "curried" version of se_clos is passed to the map function. Additionally, domain S + is the domain of non-empty sequences of signature closures (non-empty because methods are always passed in the object this/self), and domainsM and M are auxiliary domains of raw methods and methods, respectively. The function map2 is the two-dimensional version of map (i.e., takes a binary function and two input lists as its arguments.) In words, the definition of the filtering function filter states that the function takes an object o ofÔ and returns a corresponding valid object of O. If the object is invalid because of non-matching shapes in the signature closure of o and its member records, filter returns the bottom object ⊥ O (in domainÔ, ⊥ O is the closest valid object to an invalid object with non-equal shapes in its signature and records.) Otherwise, o has matching signature and record shapes but may have objects bound to its fields, or taken in or returned by its methods, whose signature closure does not subsign the corresponding signature closures in the signature closure of o. In this case, filter lazily constructs and returns the closest valid object in domainÔ to o, where all non-bottom fields and non-bottom methods of o are guaranteed (via functions filter-obj-sig and filter-meth-sig, respectively) to have signature closures that subsign the corresponding signature closures in the signature closure of o.
Function filter-obj-sig checks if its input object o has a signature closure s that subsigns a required declared signature closure ss. If s is not a subsignature of ss, filter-obj-sig returns ⊥ O . If it is, the function calls filter on o, thereby returning the closest valid object to o.
For methods, when filter-meth-sig is applied to a method m it returns a valid method that when applied to the same input os ∈Ô + as m, returns the closest valid object to the output object of m that subsigns the declared output signature closure out_s corresponding to the sequence of valid objects closest (component-wise) to os that (again, component-wise) subsigns the declared sequence of input signature closures in_s prepended with the signature closure of the object enclosing m (to properly filter the first argument object in os, which is the value for this/self.) Having defined the filtering function filter, the proof that domain O, as defined by filter, is a well-defined computable subdomain ofÔ is presented in Appendix B.
6.2. Class Types. As constructed, NOOP is a nominal model of OOP, because objects of domain O of NOOP include signatures specifying the associated class contracts maintained by the objects (including inherited contracts.) This nominal information encoded in signatures provides a framework for naturally partitioning the domain of NOOP objects into sets defining class types, where a type is a set of similar objects.
First, we define exact class types. The exact class type corresponding to a class C is the set of all objects tagged with the signature closure for C. 5 Next, it should be noted that a cardinal principle of nominally-typed mainstream OOP is that objects from subclasses of a class C conform to the contract of class C and can be used in place of objects constructed using class C (i.e., in place of objects in the exact class type of C.) Hence, the natural type associated with class C, called the class type corresponding to or designated by C, consists of the objects in class C plus the objects in all subclasses of class C. In nominally-typed OO languages, the class type designated by class C is not the exact class type for C but the union of all exact types corresponding to classes that subclass (i.e., inherit from) class C, including class C itself.
Motivated by this discussion, we define class types in NOOP as interpretations of signature closures. For a signature closure sc, its interpretation S[sc] is a subdomain of domain O, having the same underlying approximation ordering of domain O and whose universe is defined by the equation In other words, the class type designated by a class is the interpretation of the signature closure sc corresponding to the class, which, in turn, is the set of all objects in domain O of NOOP with a signature closure scs that subsigns sc, or the bottom object ⊥ O . Given that subsigning in NOOP models OO inheritance, the definition of NOOP class types is in full agreement with intuitions of mainstream OO developers.
Having defined class types, it should be noted that a class type S[sc] is always a non-empty domain (i.e., always has some non-bottom object) because the object a m } is the fields shape of sc and {b 1 , · · · , b n } is the methods shape of sc) is always a valid constructed object (i.e., is an object of domainÔ of preNOOP that passes filtering to domain O of NOOP.) This object is a member of S[sc] by Equation (5). The non-emptiness of class types is used in the proof of the identification of inheritance and subtyping.
6.3. Inheritance is Subtyping. After we constructed NOOP, and after we defined class types in agreement with intuitions of mainstream OO developers, we can now easily see what it means for nominally-typed OO type systems to completely identify inheritance and subtyping. We express this statement formally as follows: Two signature closures corresponding to two classes are in the subsigning relation if and only if the class types denoted by the two signature closures are in the subset relation (i.e., the two classes are in the inheritance relation if and only if the corresponding class types are in the nominal subtyping relation.) We prove the correspondence between inheritance and subtyping in the following theorem.
Theorem 6.1. For two signature closures sc 1 and sc 2 denoting class types S[sc 1 ] and S[sc 2 ], we have Proof. Based on Equation (5), and the non-emptiness of class types, the proof of this theorem is simple. We should notice in the proof above that it is the nominality of objects of NOOP (i.e., the embedding of signature closures into objects) that makes S[sc 2 ] being a superset of S[sc 1 ] imply that sc 1 has sc 2 as one of its supersignatures, and vice versa. The simplicity of the proof is a clear indication of the naturalness of the definitions for class signatures and class types.

NOOP Compared to Structural Models of OOP
Having presented NOOP, in this section we briefly compare NOOP to the most well-known structural domain-theoretic models of OOP, namely the model of Cardelli, which we call SOOP, and that of Cook, which we call µSOOP.
Comparing NOOP to SOOP and µSOOP reveals that NOOP includes full class name information while SOOP and µSOOP totally ignore this information, based on the different views of type names adopted by each of the models. Objects in SOOP and µSOOP are viewed as mere (plain) records, while in NOOP they are viewed as records that maintain contracts, which are referred to via nominal information, with nominal information being part of the identity of NOOP objects.
NOOP, SOOP and µSOOP also have different views of types, type inheritance and subtyping, where behavioral contracts (via type name information) are part of the identity of types in NOOP, and thus are respected in type inheritance and subtyping, but contracts are ignored in SOOP and µSOOP. In addition, NOOP and µSOOP model recursive types, while SOOP does not. This leads NOOP (due to nominality) and SOOP (due to lack of recursive types) to identify type inheritance with OO subtyping while µSOOP breaks that identification.
More details on the differences and similarities between NOOP, SOOP and µSOOP can be found in (AbdelGawad, 2016a).

Conclusions
Based on realizing the semantic value of nominal-typing, in this paper we presented NOOP as a model of OOP that includes nominal information found in nominally-typed mainstream OO software. The inclusion of nominal information as part of the identity of objects and class types in NOOP led us to readily prove that type inheritance, at the syntactic level, and subtyping, at the semantic level, completely agree in nominally-typed OOP. A comparison of NOOP to structural models of OOP revealed nominal and structural models of OOP have different views on fundamental notions of OOP. It is necessary, we thus believe, to include nominal information in any accurate model of nominally-typed mainstream OOP. By its inclusion of nominal information, NOOP offers a chance to understand and advance OOP and current OO languages based on a firmer semantic foundation.

Future Work
One immediate possible future work that can be built on top of research presented in this paper is to define a minimal nominally-typed OO language, e.g., in the spirit of FJ (Igarashi et al., 2001), then, in a standard straightforward manner, give the denotational semantics of program constructs of this language in NOOP. The type safety of this language can then be proven using the given denotational semantics.
Generics add to the expressiveness of type systems of nominally-typed OO programming languages (Bank et al., 1996;Bracha et al., 1998;Cartwright & Steele, 1998;Langer, 2015;Bloch, 2008;Gosling et al., 2014;CSh, 2015;Sca, 2014). Another possible future work that can be built on top of NOOP is to produce a denotational model of generic nominally-typed OOP. Such a model may provide a chance for a better analysis of features of generics in nominally-typed mainstream OO languages and thus provide a chance for suggesting improvements and extensions to the type systems of these languages.
To illustrate the definitions of signature constructs given in Section 5, in this appendix we present a few examples of signature constructs. Assuming the following OO class definitions (in Java-like pseudo-code), and, hence, define signature environments ObjSigEnv = {ObjSig, BoolSig}, and P airSigEnv = {ObjSig, BoolSig, P airSig}, and the signature closures ObjSigClos = (Object, ObjSigEnv), and P airSigClos = (Pair, P airSigEnv).
We can immediately see, using the definition of extension and the definitions of immediate subsigning and subsigning in Section 5, that P airSigEnv ◭ ObjSigEnv, P airSigClos 1 ObjSigClos, and P airSigClos ObjSigClos. The last conclusion expresses the fact that class Pair inherits from class Object, and the second to last conclusion expresses that class Pair is an immediate subclass of class Object (The reader is encouraged to find other similar conclusions based on the definitions of classes Object, Boolean and Pair given above.)

Appendix B. Proofs
In this appendix we present proofs of main theorems in this paper, pertaining to the properties of the records domain constructor ⊸, and to the filtering of preNOOP to NOOP. These proofs ascertain the well-definedness of ⊸ and of the filtering, and thus their appropriateness for being used in constructing NOOP.

B.1. The Domain of Record Functions has an Effective Presentation.
It is straightforward to confirm that ⊸ constructs a domain. To prove that ⊸ constructs domains given an arbitrary domain D and a domain L (with a fixed interpretation as a flat domain of labels), we build an effective presentation of the finite elements of L ⊸ D, assuming an effective presentation of the finite elements of D and L. We prove that these finite elements form a finitary basis of the records domain. Since L has a fixed interpretation, domain constructor ⊸ can be considered as being parametrized only by domain D.
Given an effective presentation L of L where L = [⊥ L , l 1 , l 2 , · · · ], we define, for all n ∈ N, the finite sequences where 0 < j 1 < · · · < j k , and The size k, of L n , is the number of ones in the binary expansion of n, and thus k ≤ log 2 (n + 1) with equality only when n is one less than a power of 2. k = 0 only when n = 0, and in this case L 0 = [] (the empty label sequence) 6 . It is easy to confirm that there is a one-to-one correspondence between the set of natural numbers N and the set of distinct finite label sequences L n .
where, again, k is the number of ones in the binary expansion of n, and zip([l j1 , · · · , l j k ], [d n1 , · · · , d n k ]) = {(l j1 , d n1 ), · · · , (l j k , d n k )}. 6 The definition of Ln is patterned after a similar construction presented in Dana Scott's "Data Types as Lattices" (Scott, 1976). Unlike the case in Scott's construction, n here, in the LHS of Equation (7), is doubled-i.e., the binary expansion of n is "shifted left" by one position-to guarantee j i > 0, and thus guarantee that l 0 = ⊥ L is never an element of Ln.
Given the decidability of the consistency (· ↑ D ·) and lub (· ⊔ D · = ·) relations for finite elements of D, the presentation R of the finite elements of R is effective, since, for record functions r and r ′ as defined in Section 4.2, under the approximation ordering defined by Equation 4.2, the consistency relation is decidable (given the finiteness of records), and the lub relation Proof. Given the countability of L and of the finite elements of D, elements of R are countable. A consistent pair of elements r, r ′ ∈ R, according to Equation (8), has a lub r ⊔ R r ′ defined by Equation (9). Given that D is a domain, the lub d ⊔ D d ′ of all consistent pairs of finite elements d, d ′ in D exists, thus the lub r ⊔ R r ′ also exists.
Lemma B.1 actually proves that ⊸ is a computable function that maps a pair of a flat domain and a domain to the corresponding record domain. The presumption is that no effective presentation is necessary for the flat domain because distinct indices for elements of L will simply mean distinct labels l i . If L is a flat countably infinite domain (which implies it has an effective presentation) and D is an arbitrary domain, then the lemma asserts that L ⊸ D is a domain with an effective presentation that is constructible from the effective presentations for L and D. Proof. First, we prove that ⊸ is monotonic with respect to the subset relation on the universe of its input, i.e., that |D| ⊆ |D ′ | ⇒ |L ⊸ D| ⊆ |L ⊸ D ′ |. Then, given that the approximation ordering on D (as a subdomain of D ′ ) is the restriction of the approximation ordering on D ′ , we prove that the elements of L ⊸ D (as members of L ⊸ D ′ ) form a domain under the approximation ordering of L ⊸ D ′ , and thus that L ⊸ D is a subdomain of L ⊸ D ′ .
Since |D| ⊆ |D ′ |, then {d 1 , · · · , d k } ⊆ |D| =⇒ {d 1 , · · · , d k } ⊆ |D ′ |. For arbitrary L f where |L f | = {⊥ L , l 1 , · · · , l k }, we thus have Thus, |L f ⊸→ D| ⊆ |L f ⊸→ D ′ |. Accordingly, for sets R(L f , D) (the elements of L ⊸ D with tag tag(L f \{⊥ L })) and R(L f , D ′ ) (the elements of L ⊸ D ′ with tag tag(L f \{⊥ L })), as defined in Equation 2 of Section 4.2, we have R(L f , D) ⊆ R(L f , D ′ ). Thus, Thus, Next, since D is a subdomain of D ′ when restricted to elements of D, we know: (i) the approximation relation on D is the approximation relation on D ′ restricted to D; (ii) consistent pairs of D are consistent pairs in D ′ ; and (iii) lubs, in D, of consistent pairs of elements of D are also their lubs in D ′ . Thus, for d i , d j ∈ D, Hence, according to the definition of the approximation, consistency and lub relations for ⊸ (Equations (4.2), (8) and (9)), the lub, in L ⊸ D, of a consistent pair of records is also their lub in L ⊸ D ′ . That is, respectively, for r, r ′ ∈ |L ⊸ D|, we have r ↑ (L⊸D) r ′ ⇔ r ↑ (L⊸D ′ ) r ′ and (13) r ⊔ (L⊸D) r ′ = r ⊔ (L⊸D ′ ) r ′ .
In addition to being monotonic, continuity of a domain constructor asserts that the lub of domains it constructs using a chain of input domains is the domain it constructs using the lub of the chain of input domains (i.e., that, for ⊸, the lub D of a chain of input domains D i gets mapped by ⊸ to the lub, say domain R, of the chain of output domains R i = L ⊸ D i .)

Lemma B.3 (⊸ preserves lubs.). For a chain of domains
Proof. Let Q be the lub of the chain of domains R i = L ⊸ D i (R i 's form a chain by the monotonicity of ⊸.) Domain Q is thus the union of domains R i , i.e., Q = ⊔R i = i (L ⊸ D i ).
Domain Q is equal to R = L ⊸ D = L ⊸ i D i because each element q in Q (q is a record function) is an element of a domain L ⊸ D i for some i. Given D i is a subset of D = i D i , q will also appear in R.
Similarly, a record function r in R is an element of a domain L ⊸ D i for some i, because every finite subset of i D i has to appear in one D i (given that D i is a chain of domains.) Thus, by the definition of Q, r is also a member of Q.
This proves that Q = R.
Lemmas B.2 and B.3 prove that ⊸ is computable given effective presentations for L and D (or, equivalently, an effective presentation for D.) B.3. Filtering is a Finitary Projection. In this section we prove that function filter, as defined in Section 6.1, is indeed a finitary projection, and thus that the domain O of valid objects (Definition 6.1 in Section 6.1) defined by the filtering function is a subdomain of Scott's universal domain U, and thus is indeed a domain.
To do so, we first prove a number of auxiliary propositions regarding domainÔ. Proof. By strong induction on rank of objects.
To prove that filter defines a projection, in the sequel we use the inductivelydefined predicate valid (as defined by Definition 6.1 in Section 6.1) that applies to objects ofÔ. Note that, in addition to ⊥ O , objects with empty field and method records provide base cases for the definition of valid.

Lemma B.4 (filter returns the closest valid object that approximates its input object). For an object o ofÔ, filter(o)⊑o ∧ valid(filter(o)) ∧ ∀o
Proof. By strong induction on rank of objects, noting that, for the base case, filter(o) diverges (i.e., "returns" ⊥ O ) for the rank 0 input object ⊥ O , and if an object o of rank 1 is invalid then filter(o) also returns ⊥ O (no distinct objects of rank 1 approximate each other.) Proposition B.1 is used for the inductive case.
Theorem B.1. filter is a finitary projection.
Proof. We prove that filter is a finitary projection, on four steps.
(3) filter is a continuous function Proof. Direct, from the continuity of functions used to define filter (such as rec-shp, map, se_clos, etc.), and noting the closure of continuous functions under composition and lambda abstraction.
(4) filter is finitary Proof. The condition in point 2 of Theorem 8.5 in (Cartwright et al., 2016), namely a(x) = {y ∈ O|∃x ′ ∈ x.x ′ ax ′ ∧ y ⊑ x ′ }, can be rewritten for the filtering function filter as (14) filter ( Objects of domainÔ are in one-to-one correspondence with principal ideals over their finitary basis. The filtering function filter returns, as its output, the closest valid object to its input object (The object returned is a well-defined object, and it is a fixed point of the filtering function.) Thus, given that objects correspond to strong ideals in the finitary basis ofÔ, they correspond to downward-closed sets. Condition (14) is thus true for all objects inÔ.
Based on the definition of finitary projections, function filter is thus a finitary projection.