Lecture 2updated2015v3.pptx

Post on 09-Jul-2016

220 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

Transcript

HIT3155 Languages in Software Development Lecture 2

Semester 1, 2015

Dr. Pan Zheng

Recall what is “language” Language definition can be loosely divided into:

Syntax, or structure Semantics, or meaning

Several notational systems have been developed for language semantics:

Operational semantics Denotational semantics Axiomatic semantics

Testing vs. logical reasoning

Q.E.D : quod erat demonstrandum(that which was to be proved)

Logical reasoning

Axioms:-The set of facts wehave to work with. Theorems:-

Built from our axiomsbased on inference/ deduction rules.

Deductive Logic: Detachment → 𝑃 𝑄 , 𝑃 𝑄Ryan Gosling → Look good, Ryan Gosling

Look good

Deductive logic: syllogism → 𝑃 𝑄, → , 𝑄 𝑅 𝑃 𝑅Ryan Gosling → Great hair,Great hair → Look good, Ryan Gosling

Look good

The Hilbert-style Proof System A Hilbert-style proof system consists of axioms and proof rules: An axiom of a proof system is a formula that is provable by

definition. An inference rule asserts that if some list of formulae is

provable, then so is another formula. A proof is a structured object built from formulae according to

constraints established by a set of axioms and inference rules.

The Hilbert-style Proof System The rule format:

We construct a proof from proofs:

Axiomatic Semantics The axiomatic semantics is a formal (proof) system for deriving

equations between expressions. it describes only what a program does The basic idea of the axiomatic method is to define the

meaning of language elements indirectly using logical assertions.

For example, we can write

{P}Q{R} called a Hoare triple, to state that if the Boolean expression P holds prior the

computation of Q, and if Q terminates, then the Boolean expression R must hold as well.

Hoare Triple

{P}Q{R}

In other words, if we start with a store σ in which Pre holds and the execution of Q with respect to σ terminates and yields a store σ ′ , then Post holds in store σ ′

Precondition PostconditionProgram

what needs to be satisfiedin order for everything to be true, specifies what the program expects before execution

what is true if the precondition is satisfied AND the programexecutes.

“If Pre holds before executing Q, and Q terminates, then R holds after Q.

Hoare Triple Pre-conditions and post-conditions can be regarded as

interfaces or contracts between the program and its clients They help users to understand what the program is supposed

to yield without needing to understand how the program executes. (like a blackbox)

Typically, programmers write them as comments for procedures and functions as documentation and to make it easier to maintain programs.

Such specifications are especially useful for library functions for which the source code is often not available to the users.

serve as contracts between the library developers and users of the library

Hoare Triple the comments describe the intent of the developer, but they do

not give a guarantee of correctness. Axiomatic semantics addresses this problem.

It shows how to rigorously describe (partial) correctness statements and how to establish correctness using formal reasoning.

Example of Hoarse Triples { } = 5{ = 5}𝑡𝑟𝑢𝑒 𝑥 ∶ 𝑥 { = } = + 3{ = + 3}𝑥 𝑦 𝑥 ∶ 𝑥 𝑥 𝑦 { > 0} = 2 { > −2}𝑥 𝑥 ∶ 𝑥 ∗ 𝑥 { = } < 0 = − { = | |}𝑥 𝑎 𝑖𝑓 𝑥 𝑡ℎ𝑒𝑛 𝑥 ∶ 𝑥 𝑥 𝑎 { } = 3{ = 8}𝑓𝑎𝑙𝑠𝑒 𝑥 ∶ 𝑥 { } + 1{𝑡𝑟𝑢𝑒 𝑤ℎ𝑖𝑙𝑒 𝑡𝑟𝑢𝑒 𝑑𝑜 𝑥 ≔ 𝑥 𝑓𝑎𝑙𝑠𝑒}

Hoarse Triples : Assignment {P}x:=x+1{x ≤ N}

Assignment/Substitution rule {P0}x:=f{P} Where x is a variable identifier; P0 is obtained from P by substituting f for all occurrences of x

so please find the precondition of this…

Example: exercise

{x+1 ≤ }x:=x+1{ ≤ }𝑁 𝑥 𝑁or even better

{x ≤ -1}x:=x+1{ ≤ }𝑁 𝑥 𝑁

Hoarse Triples :Sequence Sequence rule

{P}x:=x+1;y:=x+y{y>5} Refer to whiteboard ...

Hoarse Triples : Condition Conditional rule

The if commands involves a choice between alternatives. Two paths lead through an if command, if we can prove each

path is correct given the appropriate values of the Boolean expression, the entire command is correct

Hoarse Triples : Condition For example, a proof of {0 ≤ x ≤ 15 } if x < 15 then x := x + 1 else x := 0 endif {0 ≤ x ≤ 15 } needs to apply the conditional rule, which in turn requires to prove { 0 ≤ x ≤ 15 ∧ x < 15 } x:=x+1 { 0 ≤ x ≤ 15 }, or simplified {0 ≤ x < 15 } x:=x+1 {0 ≤ x ≤ 15 } for the then part,

AND {0 ≤ x ≤ 15 x ≥ 15} x:=0 {0 ≤ x ≤ 15}, or simplified∧ {x=15} x:=0 {0 ≤ x ≤ 15 } for the else part.

Hoarse Triples : Condition Another example Premise 1:

Premise 2:

Proof:

Operational Semantics The purpose of operational semantics is to describe how a computation

is performed. The operational semantics is based on a directed form of equational

reasoning called “reduction”. Reduction may be regarded as a form of symbolic evaluation.

The basic idea of the operational method is to define the meaning of the language elements by means of a (labelled) transition system.

The operational semantics definition provides means to display the computation steps undertaken when a program is evaluated to its output.

Some forms of operational semantics are interpreted-based, with instruction counters, data structures, and the like, and others are inference rule-based, with proof trees that show control flows and data dependencies.

Operational Semantics

Denotational Semantics The denotational semantics, or model theory, is defined in the spirit of

equational logic or first-order logic. A denotational semantics definition (model) consists of a family of sets, one for each type, with the property that each well-typed expression may be interpreted as a specific element of the appropriate set.

The denotational semantics is a recursive definition that maps well-typed derivation trees to their mathematical meanings. For example, the set Bool consists of two meanings: Bool = {true, false} and an operation

not : Bool Bool with not(false) = true, not(true) = false. The denotational method does not maintain states, but the meaning of a

program is given as a function that interprets all language elements of a given program as elements of a corresponding set of values.

Denotational Semantics

Types and Type Systems Types are collections of values that share some common properties. When we

say that v is a value of type T, we mean that v T∈ . In some systems, there may be types with types as members. Types with types

as members are usually called something else, such as universes, orders, or kinds, to avoid the impression of circularity.

In a type system, types provide a division or classification of some universe of possible values. A type system defines in a mathematical way (axioms and deduction-rules), which expressions are typable,

i.e., which expressions can be assigned a valid type using the underlying type system.

In most programming languages, types are “checked” in some way, either during program compilation, or during execution. The main purpose of type checking is the detection of errors, documentation, program optimization, etc.

Values In computer science we classify as a value everything that may

be evaluated, stored, incorporated in a data structure, passed as an argument to a procedure or function, returned as a function result, and so on.

In computer science, as in mathematics, an “expression” is used (solely) to denote a value.

Which kinds of values are supported by a specific programming language is heavily depended on the underlying paradigm and its application domain.

Most programming languages share some basic sets of values like truth values, integers, real number, records, lists, etc.

Constants Constants are named abstractions of values. Constants are used to assign an user-defined meaning to a value. Examples:

EOF = -1 TRUE = 1 FALSE = 0 PI = 3.1415927 MESSAGE = ”Welcome to HIT3315”

• Constants do not have an address, i.e., they do not have a location. • At compile time, applications of constants are substituted by their

corresponding definition.

Constants Constants are named abstractions of values. Constants are used to assign an user-defined meaning to a value. Examples:

EOF = -1 TRUE = 1 FALSE = 0 PI = 3.1415927 MESSAGE = ”Welcome to HIT3315”

• Constants do not have an address, i.e., they do not have a location. • At compile time, applications of constants are substituted by their

corresponding definition.

Primitive Values Primitive values are these values that cannot further

decomposed. Some of these values are implementation and platform dependent.

Examples: Truth values Integers Characters Strings Real numbers

Composite Values Composite values are built up using primitive values and

composite values. The layout of composite values is in general implementation dependent.

Examples: Records Arrays Enumerations Sets Lists Tuples Files

Pointers Pointers are references to values, i.e., they denote locations of a

values. Pointers are used to store the address of a value (variable or

function) – pointer to a value, and pointers are also used to store the address of another pointer – pointer to pointer.

In general, it not necessary to define pointers with a greater reference level than pointer to pointer.

In modern programming languages, we find pointers to variables, pointers to pointer, function pointers, and object pointers, but not all programming languages provide means to use pointers directly (e.g., Java, Scheme).

A Language Interpreter An interpreter consists of two parts:

A front end that converts program text (a program in the source language)

to a abstract syntax tree (the internal representation of the program text) and

• An evaluator (the actual interpreter) that looks at a data structure and performs some associated actions, which depend on the actual data structure.

In case of a language-processing system, the interpreter takes the abstract syntax tree and converts it, possibly using external inputs, to an answer.

Examples:• A calculator, • Basic, • Perl, Python, sh, awk, Tcl• JVM

Execution via Interpreter

A Language Compiler A compiler translates program text into some other language

(the target language). The building blocks of a compiler are:

A front end that converts program text (a program in the source language) to a abstract syntax tree (the internal representation of the program text),

A set of independent compiler phases, each has assigned a particular task in the compilation process (e.g. semantics analysis, optimization, register allocation, code emission), and

The evaluator of a compiled languages may be an interpreter (e.g. JVM) or simply a hardware machine (e.g. von Neumann computer).

• Examples of compiled languages:• C/C++, C#• Pascal, Java

Execution via Compiler

Programming Language Values In the specification of programming languages we have always

at least two sets of values:

Expressed values – values that can be specified by means of (literal) expressions in the given programming language (result of expression)

Examples: numbers, pairs, characters, strings

Denoted values – values that are bound to names (meaning of a variable)

Examples: variables, parameters, procedures

Source, Host, and Target Language The source language is the language in which we write

programs that should be evaluated by an interpreter or compiled by a compiler.

The host language is the language in which we specify the interpreter or compiler.

The target language is the language a source language in translated into by a compiler.

A target language may be a higher-level programming language (e.g., C) or assembly language or machine language.

Compiler Interpreter

Compiler Takes Entire program as input Translates program one statement at a time.

Intermediate Object Code is Generated No Intermediate Object Code is Generated

Conditional Control Statements are Executes faster

Conditional Control Statements are Executes slower

Memory Requirement : More(Since Object Code is Generated)

Memory Requirement is Less

Program need not be compiled every time Every time higher level program is converted into lower level program

Errors are displayed after entire program is checked

Errors are displayed for every instruction interpreted (if any)

generates the error message only after scanning the whole program. Hence debugging is comparatively hard.

Continues processing the program until the first error is met, in which case it stops. Hence debugging is easy

Interpreter

compiler

End of lecture 2

top related