Algebraic Specification and Abstract Data Types An abstract
Algebraic Specification and Abstract Data Types • An abstract data type is typically characterized by a set of operations that – – constructured data from primitive data extract primitive data from a data structure modify the contents of a data structure test properties of the data structure • Programming languages providing abstract data types provide constructs to – represent the specification of the data type and its operations – implement the representation of the data type and operations upon it. Lecture #30 PLP Spring 2004, UF CISE 1
Algebraic Specification • An algebra is specified by giving a sort (this is the name of a set), and a set of signatures (this is a set of function specifications). • For example, think of a simple algebra for arithmetic with addition and subtraction: <S, {+: S Χ S → S, -: S Χ S → S}> • The specification of an algebra is an abstract entity. We can create a associate a particular algebra with the specification by associating a set (called the carrier set) with the sort and a specific function with each operator symbols in the signatures. • Properties of any particular algebra (or model of an algebra) are specified by giving axioms such as -(+(x, y)=x Lecture #30 PLP Spring 2004, UF CISE 2
Algebraic Specification of the Data Type of Complex Numbers type complex imports real operations: +: complex Χ complex → complex -: complex Χ complex → complex *: complex Χ complex → complex /: complex Χ complex → complex -: complex → complex makecomplex: real Χ real → complex realpart: complex → real imaginarypart: complex → real variables: x, y, z: complex; r, s: real axioms: realpart(makecomplex(r, s)) = r imaginarypart(makecomplex(r, s)) = s realpart(x+y) = realpart(x) + realpart(y). . . • There actually some problems with this specification. For example, how can it handle division by 0 (which yields an error)? Lecture #30 PLP Spring 2004, UF CISE 3
Consider the specification of a queue data type • • • type queue(element) imports boolean operations: createq: queue enqueue: queue Χ element → queue dequeue: queue → queue frontq: queue → element emptyq: queue → boolean variables: q: queue, x: element axioms: emptyq(createq) = true emptyq(enqueue(q, x)) = false frontq(createq) = error frontq(enqueue(q, x)) = if emptyq(q) then x else frontq(q) dequeue(createq) = error dequeue(enqueue(q, x)) = if emptyq(q) then q else enqueue(dequeue(q), x) Note the use of a data type parameter, element If you look at the signature of frontq, you see that it’s supposed to return a boolen, but axiom 3 requires that it be able to return something called error. This axiom does not follow the rules. Note a similar problem for dequeue. Louden introduces the idea of a constructor (that creates a new object of the data type being defined) and an inspector (that retrieves previously constructed values). But note that dequeue is defined constructively, in terms of the queue value that it returns which is created by calling enqueue. Evaluate dequeue(enqueue(enqueue(createq, 1), 2), 3), 4). However, because this same value was constructed previously, we say this is an inspector. In Louden’s nomenclature, the inspector frontq is a selector, and inspector emptyq is a predicate. Lecture #30 PLP Spring 2004, UF CISE 4
How do we know what axioms to create? • For a given data type, we typically want an axiom for each inspector involving each constructor. • Consider the data type of problem 9. 14 having these operations: create: Symbol. Table enter: Symbol. Table X name X value → Symbol. Table lookup: Symbol. Table X name → value isin: Symbol. Table X name → boolean • What are the inspectors and constructors? lookup(create, x) = error isin(create, x) = false lookup(enter(S, x, v), y) = if (y=x) then v else lookup(S, y) isin(enter(S, x, v), y) = if (y=x) then true else lookup(S, y) Lecture #30 PLP Spring 2004, UF CISE 5
- Slides: 5