A Theory of Name Resolutionvjovanov.github.io/dsldi-summer-school/materials/...Static Name...

Post on 04-Jul-2020

5 views 0 download

Transcript of A Theory of Name Resolutionvjovanov.github.io/dsldi-summer-school/materials/...Static Name...

A Theory of Name Resolution

1 2

Guido Wachsmuth

Eelco Visser

Pierre Neron

Andrew Tolmach

111 2

[ESOP15]

Static Name Resolution

module A {

def s = 5

}

module B {

import A

def x = 6

def y = 3 + s

def f =

fun x { x + y }

}

Static Name Resolution

module module

def import def def defA

A

B

6 y funf

x +

x y

x +

3 s

5s

module A {

def s = 5

}

module B {

import A

def x = 6

def y = 3 + s

def f =

fun x { x + y }

}

Static Name Resolution

module module

def import def def defA

A

B

6 y funf

x +

x y

x +

3 s

5s

module A {

def s = 5

}

module B {

import A

def x = 6

def y = 3 + s

def f =

fun x { x + y }

}

Static Name Resolution

module module

def import def def defA

A

B

6 y funf

x +

x y

x +

3 s

5s

module A {

def s = 5

}

module B {

import A

def x = 6

def y = 3 + s

def f =

fun x { x + y }

}

Static Name Resolution

module module

def import def def defA

A

B

6 y funf

x +

x y

x +

3 s

5s

module A {

def s = 5

}

module B {

import A

def x = 6

def y = 3 + s

def f =

fun x { x + y }

}

Static Name Resolution

module module

def import def def defA

A

B

6 y funf

x +

x y

x +

3 s

5s

module A {

def s = 5

}

module B {

import A

def x = 6

def y = 3 + s

def f =

fun x { x + y }

}

Use Scope Graphs toDescribe Name Resolution

Use Scope Graphs toDescribe Name Resolution ??

Name Resolution is Pervasive

Name Resolution is Pervasive

Appears in many different artifacts…

Name Resolution is Pervasive

Appears in many different artifacts…

Compiler

Parsing Semantics Analysis

Code Genenation

SymbolTable

Name Resolution is Pervasive

Appears in many different artifacts…

Semantics

x : ⌧1,� ` e : ⌧2� ` �x.e : ⌧1 ! ⌧2

�(x) = ⌧

� ` x : ⌧

Compiler

Parsing Semantics Analysis

Code Genenation

SymbolTable

Name Resolution is Pervasive

Appears in many different artifacts…

Semantics

x : ⌧1,� ` e : ⌧2� ` �x.e : ⌧1 ! ⌧2

�(x) = ⌧

� ` x : ⌧

Compiler

Parsing Semantics Analysis

Code Genenation

SymbolTable

IDE

Name Resolution is Pervasive

Appears in many different artifacts…

… with rules encoded in many different ad-hoc ways Semantics

x : ⌧1,� ` e : ⌧2� ` �x.e : ⌧1 ! ⌧2

�(x) = ⌧

� ` x : ⌧

Compiler

Parsing Semantics Analysis

Code Genenation

SymbolTable

IDE

Name Resolution is Pervasive

Appears in many different artifacts…

… with rules encoded in many different ad-hoc ways Semantics

x : ⌧1,� ` e : ⌧2� ` �x.e : ⌧1 ! ⌧2

�(x) = ⌧

� ` x : ⌧

Compiler

Parsing Semantics Analysis

Code Genenation

SymbolTable

IDE

Name Resolution is Pervasive

Appears in many different artifacts…

… with rules encoded in many different ad-hoc ways Semantics

x : ⌧1,� ` e : ⌧2� ` �x.e : ⌧1 ! ⌧2

�(x) = ⌧

� ` x : ⌧

Compiler

Parsing Semantics Analysis

Code Genenation

SymbolTable

IDE

x:int, 𝚪

[3/x].𝛔

Name Resolution is Pervasive

Appears in many different artifacts…

… with rules encoded in many different ad-hoc ways Semantics

x : ⌧1,� ` e : ⌧2� ` �x.e : ⌧1 ! ⌧2

�(x) = ⌧

� ` x : ⌧

Compiler

Parsing Semantics Analysis

Code Genenation

SymbolTable

IDE

x:int, 𝚪 lookup(xi)

[3/x].𝛔

Name Resolution is Pervasive

Appears in many different artifacts…

… with rules encoded in many different ad-hoc ways Semantics

x : ⌧1,� ` e : ⌧2� ` �x.e : ⌧1 ! ⌧2

�(x) = ⌧

� ` x : ⌧

Compiler

Parsing Semantics Analysis

Code Genenation

SymbolTable

IDE

x:int, 𝚪 lookup(xi)

[3/x].𝛔

No standard approach, no re-use

Contrast with Syntax

Contrast with Syntax

A standardformalism

Context-Free

Grammars

Contrast with Syntax

A unique definition

A standardformalism

program = decl

decl = module id { decl

⇤}

| import qid

| def id = exp

exp = qid

| fun id { exp }

| fix id { exp }

| let bind

⇤in exp

| letrec bind

⇤in exp

| letpar bind

⇤in exp

| exp exp

| exp � exp

| int

qid = id

| id . qidbind = id = exp

Context-Free

Grammars

Contrast with Syntax

A unique definition

A standardformalism Supports

Parser

AST

Pretty-Printing

program = decl

decl = module id { decl

⇤}

| import qid

| def id = exp

exp = qid

| fun id { exp }

| fix id { exp }

| let bind

⇤in exp

| letrec bind

⇤in exp

| letpar bind

⇤in exp

| exp exp

| exp � exp

| int

qid = id

| id . qidbind = id = exp Highlighting

Context-Free

Grammars

Representing Bound Programs

Representing Bound Programs• Many approaches to representing the results of name

resolution within an (extended) AST, e.g. • numeric indexing [deBruijn72] • higher-order abstract syntax [PfenningElliott88] • nominal logic approaches [GabbayPitts02]

Representing Bound Programs• Many approaches to representing the results of name

resolution within an (extended) AST, e.g. • numeric indexing [deBruijn72] • higher-order abstract syntax [PfenningElliott88] • nominal logic approaches [GabbayPitts02]

• Good support for binding-sensitive AST manipulation

Representing Bound Programs• Many approaches to representing the results of name

resolution within an (extended) AST, e.g. • numeric indexing [deBruijn72] • higher-order abstract syntax [PfenningElliott88] • nominal logic approaches [GabbayPitts02]

• Good support for binding-sensitive AST manipulation

• But: Do not say how to resolve identifiers in the first place!

• Also: Can’t represent ill-bound programs

• And: Tend to be biased towards lambda-like bindings

Binding Specification Languages

Binding Specification Languages• Many proposals for domain-specific languages

(DSLs) for specifying binding structure of a (target) language, e.g. • Ott [Sewell+10] • Romeo [StansiferWand14] • Unbound [Weirich+11] • Cαml [Pottier06]

• NaBL [Konat+12]

Binding Specification Languages• Many proposals for domain-specific languages

(DSLs) for specifying binding structure of a (target) language, e.g. • Ott [Sewell+10] • Romeo [StansiferWand14] • Unbound [Weirich+11] • Cαml [Pottier06]

• NaBL [Konat+12]• Generate code to do resolution and record results

Binding Specification Languages• Many proposals for domain-specific languages

(DSLs) for specifying binding structure of a (target) language, e.g. • Ott [Sewell+10] • Romeo [StansiferWand14] • Unbound [Weirich+11] • Cαml [Pottier06]

• NaBL [Konat+12]• Generate code to do resolution and record results• But: what are the semantics of such a language?

The Missing Piece

• Answer: the meaning of a binding specification for language L should be given by a function from L programs to their “resolution structures”

The Missing Piece

• Answer: the meaning of a binding specification for language L should be given by a function from L programs to their “resolution structures”

• So we need a (uniform, language-independent) method for describing such resolution structures...

The Missing Piece

• Answer: the meaning of a binding specification for language L should be given by a function from L programs to their “resolution structures”

• So we need a (uniform, language-independent) method for describing such resolution structures...

• ...that can be used to compute the resolution of each program identifier

The Missing Piece

• Answer: the meaning of a binding specification for language L should be given by a function from L programs to their “resolution structures”

• So we need a (uniform, language-independent) method for describing such resolution structures...

• ...that can be used to compute the resolution of each program identifier

• (or to verify that a claimed resolution is valid)

The Missing Piece

Design Goals

Design Goals

• Handle broad range of language binding features...

Design Goals

• Handle broad range of language binding features...

• ...using minimal number of constructs

Design Goals

• Handle broad range of language binding features...

• ...using minimal number of constructs

• Make resolution structure language-independent

Design Goals

• Handle broad range of language binding features...

• ...using minimal number of constructs

• Make resolution structure language-independent

• Handle named collections of names (e.g. modules, classes, etc.) within the theory

Design Goals

• Handle broad range of language binding features...

• ...using minimal number of constructs

• Make resolution structure language-independent

• Handle named collections of names (e.g. modules, classes, etc.) within the theory

• Allow description of programs with resolution errors

A Theory of Name Resolution

A Theory of Name ResolutionFor statically lexically scoped languages

A Theory of Name Resolution

A standardformalism

Scope

Graphs

For statically lexically scoped languages

A Theory of Name Resolution

A unique representation

A standardformalism

Scope

Graphs

For statically lexically scoped languages

A1

SA

z1

B1

SB

S0

A2

I(A2)

D

C1

SCz2I(B2)

R

x1 B2

A Theory of Name Resolution

A unique representation

A standardformalism

Scope

Graphs

Supports

Resolution

𝜶-equivalence

IDE Navigation

Refactoring tools

For statically lexically scoped languages

Reasoning tools

A1

SA

z1

B1

SB

S0

A2

I(A2)

D

C1

SCz2I(B2)

R

x1 B2

Resolution Scheme

Program Scope Graph

Resolved Program

Language-dependent

Language-independent*

Resolution Scheme

Program Scope Graph

Resolved Program

Language-dependent

Language-independent*

Resolution of a reference in a scope graph: Building a path from a reference node to a declaration node following path construction rules

Resolution Scheme

Program Scope Graph

Resolved Program

Language-dependent

Language-independent*

Resolution of a reference in a scope graph: Building a path from a reference node to a declaration node following path construction rules

*Parameterized by notions of path well-formedness and ordering

Scope Graphs by Example

Simple Scopes

def y1 = x2 + 1def x1 = 5

Simple Scopes

def y1 = x2 + 1def x1 = 5

Simple Scopes

def y1 = x2 + 1def x1 = 5

Simple Scopes

S0def y1 = x2 + 1def x1 = 5

Scope

Simple Scopes

S0def y1 = x2 + 1def x1 = 5

S0

S

Declaration

Scope

Simple Scopes

S0def y1 = x2 + 1def x1 = 5

y1

x1S0

Sx

Reference

Declaration

Scope

Simple Scopes

S0def y1 = x2 + 1def x1 = 5

y1

x1S0x2

Sx

x

Reference

Declaration

Scope

Simple Scopes

Reference Step

S0def y1 = x2 + 1def x1 = 5

Sx

Sx R

y1

x1S0x2

Sx

x

Reference

Declaration

Scope

Simple Scopes

Reference Step

S0def y1 = x2 + 1def x1 = 5

Sx

Sx R

R

y1

x1S0x2

Sx

x

Reference

Declaration

Scope

Simple Scopes

Reference Step Declaration Step

S0def y1 = x2 + 1def x1 = 5

Sx

Sx R

xS

xS D

R

y1

x1S0x2

Sx

x

Reference

Declaration

Scope

Simple Scopes

Reference Step Declaration Step

S0def y1 = x2 + 1def x1 = 5

Sx

Sx R

xS

xS D

R D

y1

x1S0x2

Sx

x

Ambiguous Resolutions

S0 def x1 = 5

def x2 = 3

def z1 = x3 + 1

Ambiguous Resolutions

z1 x2

x1S0x3

S0 def x1 = 5

def x2 = 3

def z1 = x3 + 1

Ambiguous Resolutions

z1 x2

x1S0x3

RS0 def x1 = 5

def x2 = 3

def z1 = x3 + 1

Ambiguous Resolutions

z1 x2

x1S0x3

R DS0 def x1 = 5

def x2 = 3

def z1 = x3 + 1

Ambiguous Resolutions

z1 x2

x1S0x3

R

D

S0 def x1 = 5

def x2 = 3

def z1 = x3 + 1

Ambiguous Resolutions

z1 x2

x1S0x3

R D

D

S0 def x1 = 5

def x2 = 3

def z1 = x3 + 1

match t with | A x | B x => …

Ambiguous Resolutions

z1 x2

x1S0x3

R D

D

S0 def x1 = 5

def x2 = 3

def z1 = x3 + 1

Lexical Scoping

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S0

Lexical Scoping

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S1

S0

Lexical Scoping

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S1

S0

Lexical Scoping

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

z1

x1S0z2

S1

S0

Lexical Scoping

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S1

y1y2 x2

z1

x1S0z2

S1

S0

Lexical Scoping

Parent

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S1

y1y2 x2

z1

x1S0z2

S’S

S1

S0

Lexical Scoping

Parent

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S1

y1y2 x2

z1

x1S0z2

S’S

S1

S0

Lexical Scoping

Parent

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S1

y1y2 x2

z1

x1S0z2

S’S

S1

S0

Lexical Scoping

Parent

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S1

y1y2 x2

z1

x1S0z2

R

S’S

S1

S0

Lexical Scoping

Parent

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S1

y1y2 x2

z1

x1S0z2

R D

S’S

S1

S0

Lexical Scoping

Parent

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S1

y1y2 x2

z1

x1S0z2

R

S’S

S1

S0

Lexical Scoping

Parent

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S’S

S’S P

S1

y1y2 x2

z1

x1S0z2

R

S’S

Parent Step

S1

S0

Lexical Scoping

Parent

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S’S

S’S P

S1

y1y2 x2

z1

x1S0z2

R

P

S’S

Parent Step

S1

S0

Lexical Scoping

Parent

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S’S

S’S P

S1

y1y2 x2

z1

x1S0z2

R

P

D

S’S

Parent Step

S1

S0

Lexical Scoping

Parent

Well formed path: R.P*.D

def x1 = z2 5 def z1 = fun y1 { x2 + y2 }

S’S

S’S P

S1

y1y2 x2

z1

x1S0z2

R

P

D

S’S

Parent Step

Shadowingdef x3 = z2 5 7 def z1 = fun x1 { fun y1 { x2 + y2 } }

S0

S1S2

Shadowingdef x3 = z2 5 7 def z1 = fun x1 { fun y1 { x2 + y2 } }

S0

S1S2

Shadowing

S1

S2

x1

y1

y2 x2

z1

x3S0z2def x3 = z2 5 7 def z1 = fun x1 { fun y1 { x2 + y2 } }

S0

S1S2

Shadowing

S1

S2

x1

y1

y2 x2

z1

x3S0z2def x3 = z2 5 7 def z1 = fun x1 { fun y1 { x2 + y2 } }

S0

S1S2

Shadowingdef x3 = z2 5 7 def z1 = fun x1 { fun y1 { x2 + y2 } }

S1

S2

x1

y1

y2 x2

z1

x3S0z2

R

P

P

D

S0

S1S2

Shadowingdef x3 = z2 5 7 def z1 = fun x1 { fun y1 { x2 + y2 } }

S1

S2

x1

y1

y2 x2

z1

x3S0z2

D

P

R

R

P

P

D

S0

S1S2

Shadowing

D < P.p

def x3 = z2 5 7 def z1 = fun x1 { fun y1 { x2 + y2 } }

S1

S2

x1

y1

y2 x2

z1

x3S0z2

D

P

R

R

P

P

D

S0

S1S2

Shadowing

D < P.p

s.p < s.p’p < p’

def x3 = z2 5 7 def z1 = fun x1 { fun y1 { x2 + y2 } }

S1

S2

x1

y1

y2 x2

z1

x3S0z2

D

P

R

R

P

P

D

S0

S1S2

Shadowing

D < P.p

s.p < s.p’p < p’

def x3 = z2 5 7 def z1 = fun x1 { fun y1 { x2 + y2 } }

S1

S2

x1

y1

y2 x2

z1

x3S0z2

D

P

R

R

P

P

D

R.P.D < R.P.P.D

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

A1

SA

z1

B1

SB

z2

S0

A2

x1

Associated scope

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

Associated scope

Import

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

S R1

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

Associated scope

Import

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

S R1

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

Associated scope

Import

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

S R1

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

Associated scope

Import

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

S R1

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

R

Associated scope

Import

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

S R1

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

R

S R1 R2 SR

SRS I(R1)

Import Step

Associated scope

Import

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

S R1

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

R

R

S R1 R2 SR

SRS I(R1)

Import Step

Associated scope

Import

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

S R1

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

R

RP

S R1 R2 SR

SRS I(R1)

Import Step

Associated scope

Import

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

S R1

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

R

RP

D

S R1 R2 SR

SRS I(R1)

Import Step

Associated scope

Import

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

S R1

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

I(A2)R

RP

D

S R1 R2 SR

SRS I(R1)

Import Step

Associated scope

Import

Imports

S0

SB

SAmodule A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

S R1

R2 SR

A1

SA

z1

B1

SB

z2

S0

A2

x1

I(A2)R

R

D

P

D

S R1 R2 SR

SRS I(R1)

Import Step

Imports shadow ParentsS0def z3 = 2

module A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

SA

SB

Imports shadow Parents

A1

SA

z1

B1

SB

z2

S0

A2

x1

z3S0def z3 = 2

module A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

SA

SB

Imports shadow Parents

A1

SA

z1

B1

SB

z2

S0

A2

x1

z3S0def z3 = 2

module A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

SA

SB

Imports shadow Parents

A1

SA

z1

B1

SB

z2

S0

A2

x1

I(A2)R D

z3S0def z3 = 2

module A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

SA

SB

Imports shadow Parents

A1

SA

z1

B1

SB

z2

S0

A2

x1

I(A2)R D

P

Dz3

R

S0def z3 = 2

module A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

SA

SB

Imports shadow Parents

I(_).p’ < P.p

A1

SA

z1

B1

SB

z2

S0

A2

x1

I(A2)R D

P

Dz3

R

S0def z3 = 2

module A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

SA

SB

Imports shadow Parents

I(_).p’ < P.p ⇒ R.I(A2).D < R.P.D

A1

SA

z1

B1

SB

z2

S0

A2

x1

I(A2)R D

P

Dz3

R

S0def z3 = 2

module A1 { def z1 = 5}module B1 { import A2 def x1 = 1 + z2}

SA

SB

Imports vs. IncludesS0def z3 = 2

module A1 { def z1 = 5}

import A2def x1 = 1 + z2

SA

Imports vs. IncludesS0def z3 = 2

module A1 { def z1 = 5}

import A2def x1 = 1 + z2

SA A1

SA

z1

z2

S0

A2

x1z3

Imports vs. IncludesS0def z3 = 2

module A1 { def z1 = 5}

import A2def x1 = 1 + z2

SA A1

SA

z1

z2

S0

A2

x1

R

z3 D

Imports vs. IncludesS0def z3 = 2

module A1 { def z1 = 5}

import A2def x1 = 1 + z2

SA A1

SA

z1

z2

S0

A2

x1

I(A2)

R

D

z3R

D

Imports vs. IncludesS0def z3 = 2

module A1 { def z1 = 5}

import A2def x1 = 1 + z2

SA A1

SA

z1

z2

S0

A2

x1

I(A2)

R

D

z3R

D

D < I(_).p’

Imports vs. IncludesS0def z3 = 2

module A1 { def z1 = 5}

import A2def x1 = 1 + z2

SA A1

SA

z1

z2

S0

A2

x1

I(A2)

R

D

z3R

D

D < I(_).p’ ⇒ R.D < R.I(A2).D

Imports vs. Includes

A1

SA

z1

z2

S0

A2

x1

I(A2)

R

D

z3R

D

D < I(_).p’ ⇒ R.D < R.I(A2).D

S0def z3 = 2

module A1 { def z1 = 5}

include A2def x1 = 1 + z2

SA

Imports vs. Includes

A1

SA

z1

z2

S0

A2

x1

I(A2)

R

D

z3R

D

D < I(_).p’ ⇒ R.D < R.I(A2).D

S0def z3 = 2

module A1 { def z1 = 5}

include A2def x1 = 1 + z2

SA

X

Imports vs. Includes

A1

SA

z1

z2

S0

A2

x1

I(A2)

R

D

z3R

D

D < I(_).p’

S0def z3 = 2

module A1 { def z1 = 5}

include A2def x1 = 1 + z2

SA

X

Qualified Names

module N1 { def s1 = 5}

module M1 { def x1 = 1 + N2.s2

}

S0

Qualified Names

module N1 { def s1 = 5}

module M1 { def x1 = 1 + N2.s2

}

S0

Qualified Names

module N1 { def s1 = 5}

module M1 { def x1 = 1 + N2.s2

}

S0

N1

SN

s2

S0

N2 X1

s1

Qualified Names

module N1 { def s1 = 5}

module M1 { def x1 = 1 + N2.s2

}

S0

N1

SN

s2

S0

N2 X1

s1

Qualified Names

module N1 { def s1 = 5}

module M1 { def x1 = 1 + N2.s2

}

S0

N1

SN

s2

S0

N2

R D

X1

s1

Qualified Names

module N1 { def s1 = 5}

module M1 { def x1 = 1 + N2.s2

}

S0

N1

SN

s2

S0

N2

R D

R

I(N2) D

X1

s1

def s1 = 5module N1 {

}

def x1 = 1 + N2.s2

S0

SN

Import Parents

def s1 = 5module N1 {

}

def x1 = 1 + N2.s2

S0

SN

Import Parents

def s1 = 5module N1 {

}

def x1 = 1 + N2.s2

S0

SN

Import Parents

N1

SN

s2

S0

N2 X1

s1

def s1 = 5module N1 {

}

def x1 = 1 + N2.s2

S0

SN

Import Parents

N1

SN

s2

S0

N2 X1

s1

R

I(N2)

D

P

def s1 = 5module N1 {

}

def x1 = 1 + N2.s2

S0

SN

Import Parents

N1

SN

s2

S0

N2 X1

s1

R

I(N2)

D

P

def s1 = 5module N1 {

}

def x1 = 1 + N2.s2

S0

SN

Import Parents

Well formed path: R.P*.I(_)*.D

N1

SN

s2

S0

N2 X1

s1

R

I(N2)

D

P

Transitive vs. Non-Transitivemodule A1 { def z1 = 5}module B1 { import A2}module C1 { import B2 def x1 = 1 + z2}

SA

SB

SC

Transitive vs. Non-Transitivemodule A1 { def z1 = 5}module B1 { import A2}module C1 { import B2 def x1 = 1 + z2}

SA

SB

SC

Transitive vs. Non-Transitive

??

module A1 { def z1 = 5}module B1 { import A2}module C1 { import B2 def x1 = 1 + z2}

SA

SB

SC

Transitive vs. Non-Transitive

A1

SA

z1

B1

SB

S0

A2

C1

SCz2

x1 B2

??

module A1 { def z1 = 5}module B1 { import A2}module C1 { import B2 def x1 = 1 + z2}

SA

SB

SC

Transitive vs. Non-Transitive

A1

SA

z1

B1

SB

S0

A2

I(A2)

D

C1

SCz2I(B2)

R

x1 B2

??

module A1 { def z1 = 5}module B1 { import A2}module C1 { import B2 def x1 = 1 + z2}

SA

SB

SC

Transitive vs. Non-Transitive

With transitive imports, a well formed path is R.P*.I(_)*.D

With non-transitive imports, a well formed path is R.P*.I(_)?.D

A1

SA

z1

B1

SB

S0

A2

I(A2)

D

C1

SCz2I(B2)

R

x1 B2

??

module A1 { def z1 = 5}module B1 { import A2}module C1 { import B2 def x1 = 1 + z2}

SA

SB

SC

A Calculus for Name Resolution

S R1 R2 SR

SRS I(R1)

S’S

S’S P

Sx

Sx R

xS

xS D

A Calculus for Name Resolution

S R1 R2 SR

SRS I(R1)

S’S

S’S P

Sx

Sx R

xS

xS D

Well formed path: R.P*.I(_)*.D

A Calculus for Name Resolution

S R1 R2 SR

SRS I(R1)

S’S

S’S P

Sx

Sx R

xS

xS D

Reachability

Well formed path: R.P*.I(_)*.D

A Calculus for Name Resolution

S R1 R2 SR

SRS I(R1)

S’S

S’S P

Sx

Sx R

xS

xS D

I(_).p’ < P.p

D < I(_).p’

D < P.p

s.p < s.p’p < p’

Reachability

Well formed path: R.P*.I(_)*.D

A Calculus for Name Resolution

S R1 R2 SR

SRS I(R1)

S’S

S’S P

Sx

Sx R

xS

xS D

I(_).p’ < P.p

D < I(_).p’

D < P.p

s.p < s.p’p < p’

Reachability

VisibilityWell formed path: R.P*.I(_)*.D

Theory of Scope Graphs

Scope graphs, formally5

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

declaration with name x at position i with optional associated scope S

5

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

reference with name x at position i

Scope graphs, formally

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

5

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

declaration with name x at position i with optional associated scope S

5

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

reference with name x at position i

Scope graphs, formally

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

5

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

declaration with name x at position i with optional associated scope S

5

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

reference with name x at position i

5

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

Resolution calculus, formally

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Resolution paths

Resolution calculus, formally

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Resolution pathsxi xi'

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Resolution calculus, formally

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Visibility paths

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Resolution pathsxi xi'

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Resolution calculus, formally

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

⋮Reachability paths

Visibility paths

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Resolution pathsxi xi'

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Resolution calculus, formally

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

⋮Reachability paths

Visibility paths

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Resolution pathsxi xi'

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

...may include import steps

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Resolution calculus, formally

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

⋮Reachability paths

Visibility paths

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Resolution pathsxi xi'

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

...may include import steps

References and declarations

– x

Di

:S: declaration with name x atposition i and optional associatednamed scope S

– x

Ri

: reference with name x at posi-tion i

Scope graph

– G: scope graph– S(G): scopes S in G– D(S): declarations x

Di

:S0 in S

– R(S): references x

Ri

in S

– I(S): imports x

Ri

in S

– P(S): parent scope of S

Well-formedness properties

– P(S) is a partial function– The parent relation is well-founded– Each x

Ri

and x

Di

appears in exactlyone scope S

Fig. 1. Scope graphs

Resolution paths

s := D(xDi

) | I(xRi

, x

Dj

:S) | P

p := [] | s | p · p(inductively generated)

[] · p = p · [] = p

(p1 · p2) · p3 = p1 · (p2 · p3)

Well-formed paths

WF(p) , p 2 P

⇤ · I(_,_)⇤

Specificity ordering on paths

D(_) < I(_,_)(DI)

I(_,_) < P

(IP )

D(_) < P

(DP )

s1 < s2

s1 · p1 < s2 · p2(Lex1)

p1 < p2

s · p1 < s · p2(Lex2)

Fig. 2. Resolution paths, well-formednesspredicate, and specificity ordering.

Edges in scope graph

P(S1) = S2

I ` P : S1 �! S2(P )

y

Ri

2 I(S1) \ I I ` p : yRi

7�! y

Dj

:S2

I ` I(yRi

, y

Dj

:S2) : S1 �! S2

(I)

Transitive closure

I ` [] : A ⇣ A

(N)

I ` s : A �! B I ` p : B ⇣ C

I ` s · p : A ⇣ C

(T )

Reachable declarations

x

Di

2 D(S0) I ` p : S ⇣ S

0 WF(p)I ` p · D(xD

i

) : S ⇢ x

Di

(R)

Visible declarations

I ` p : S ⇢ x

Di

8j, p0(I ` p

0 : S ⇢ x

Dj

) ¬(p0 < p))

I ` p : S 7�! x

Di

(V )

Reference resolution

x

Ri

2 R(S) {xRi

} [ I ` p : S 7�! x

Dj

I ` p : xRi

7�! x

Dj

(X)

Fig. 3. Resolution calculus

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 5

Well-founded!

Resolution Algorithm

Resolution Algorithm

• Resolution calculus says how to validate paths but not how to find them

• and reachability paths can have cycles

Resolution Algorithm

• Resolution calculus says how to validate paths but not how to find them

• and reachability paths can have cycles

• But there is a terminating resolution algorithm

• for path well-foundedness RP*I*D

• and path ordering D<I<P

Resolution Algorithm

• Resolution calculus says how to validate paths but not how to find them

• and reachability paths can have cycles

• But there is a terminating resolution algorithm

• for path well-foundedness RP*I*D

• and path ordering D<I<P

• Uses familiar notions of environments and shadowing

Resolution Algorithm v1

imperative language, explained here. The traversal is specified as a collection of(potentially) mutually recursive functions, one or more for each syntactic classof LM. Each function f is defined by a set of clauses [[pattern]]f

args

. When f isinvoked on a term, the clause whose pattern matches the term is executed. Func-tions may also take additional arguments args. Each clause body consists of asequence of statements separated by semicolons. Functions can optionally returna value using ret(). The let statement binds a metavariable in the remainder ofthe clause body. An empty clause body is written ().

The algorithm is initiated by invoking [[_]]prog on an entire LM program. Itsnet effect is to produce a scope graph via a sequence of imperative operations.The construct new

P

creates a new scope S with parent P (or no parent if p =?)and empty sets D(S), R(S), and I(S). These sets are subsequently populatedusing the += operator, which extends a set imperatively. The program scopegraph is simply the set of scopes that have been created and populated whenthe traversal terminates.

5 Resolution Algorithm

The calculus of Section 2 gives a precise definition of resolution. In principle, wecan search for derivations in the calculus to answer questions such as “Does thisvariable reference resolve to this declaration?” or “Which variable declarationsdoes this reference resolve to?” But automating this search process is not trivial,because of the need for back-tracking and because the paths in reachabilityderivations can have cycles (visiting the same scope more than once), and hencecan grow arbitrarily long.

In this section we describe a deterministic and terminating algorithm forcomputing resolutions, which provides a practical basis for implementing toolsbased on scope graphs, and prove that it is sound and complete with respectto the calculus. This algorithm also connects the calculus, which talks aboutresolution of a single variable at a time, to more conventional descriptions ofbinding which use “environments” or “contexts” to describe all the visible orreachable declarations accessible from a program location.

For us, an environment is just a set of declarations xDi

. This can be thoughtof as a function from identifiers to (possible empty) sets of declaration positions.(In this paper, we leave the representation of environments abstract; in practice,one would use a hash table or other dictionary data structure.) We construct anatomic environment corresponding to the declarations in each scope, and thencombine atomic environments to describe the sets of reachable and visible dec-larations resulting from the parent and import relations. The key operator forcombining environments is shadowing, which returns the union of the declara-tions in two environments restricted so that if a variable x has any declarationsin the first environment, no declarations of x are included from the second envi-ronment. More formally:

Definition 1 (Shadowing). For any environments E1, E2, we write:E1 / E2 := E1 [ {xD

i

2 E2 | @ xDi

0 2 E1}

A Theory of Name Resolution with Extended Coverage and Proofs

18 TUD-SERG-2015-001

where

2

ED[I, S](S) :=

(

; if S 2 SD(S)

EP [I, S](S) :=

; if S 2 SEV [I, {S} [ S](P(S))

EI [I, S](S) :=

8

<

:

; if S 2 SS

n

EL[I, {S} [ S](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I, S](S) := ED[I, S](S) / EI [I, S](S)

EV [I, S](S) := EL[I, S](S) / EP [I, S](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I, ;](S)}

ED[I](S) := D(S)

EP [I](S) := EV [I](P(S))

EI [I](S) :=S

n

EL[I](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I](S) := ED[I](S) / EI [I](S)

EV [I](S) := EL[I](S) / EP [I](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I](S)}

ED(S) := D(S)

EP (S) := EV (P(S))

EI(S) :=S

n

EL(Sy) | yRi 2 I(S) ^ y

Dj :Sy 2 Resolve(yR

i )o

EL(S) := ED(S) / EI(S)

EV (S) := EL(S) / EP (S)

Resolve(xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV (S)}

Resolution Algorithm v1

imperative language, explained here. The traversal is specified as a collection of(potentially) mutually recursive functions, one or more for each syntactic classof LM. Each function f is defined by a set of clauses [[pattern]]f

args

. When f isinvoked on a term, the clause whose pattern matches the term is executed. Func-tions may also take additional arguments args. Each clause body consists of asequence of statements separated by semicolons. Functions can optionally returna value using ret(). The let statement binds a metavariable in the remainder ofthe clause body. An empty clause body is written ().

The algorithm is initiated by invoking [[_]]prog on an entire LM program. Itsnet effect is to produce a scope graph via a sequence of imperative operations.The construct new

P

creates a new scope S with parent P (or no parent if p =?)and empty sets D(S), R(S), and I(S). These sets are subsequently populatedusing the += operator, which extends a set imperatively. The program scopegraph is simply the set of scopes that have been created and populated whenthe traversal terminates.

5 Resolution Algorithm

The calculus of Section 2 gives a precise definition of resolution. In principle, wecan search for derivations in the calculus to answer questions such as “Does thisvariable reference resolve to this declaration?” or “Which variable declarationsdoes this reference resolve to?” But automating this search process is not trivial,because of the need for back-tracking and because the paths in reachabilityderivations can have cycles (visiting the same scope more than once), and hencecan grow arbitrarily long.

In this section we describe a deterministic and terminating algorithm forcomputing resolutions, which provides a practical basis for implementing toolsbased on scope graphs, and prove that it is sound and complete with respectto the calculus. This algorithm also connects the calculus, which talks aboutresolution of a single variable at a time, to more conventional descriptions ofbinding which use “environments” or “contexts” to describe all the visible orreachable declarations accessible from a program location.

For us, an environment is just a set of declarations xDi

. This can be thoughtof as a function from identifiers to (possible empty) sets of declaration positions.(In this paper, we leave the representation of environments abstract; in practice,one would use a hash table or other dictionary data structure.) We construct anatomic environment corresponding to the declarations in each scope, and thencombine atomic environments to describe the sets of reachable and visible dec-larations resulting from the parent and import relations. The key operator forcombining environments is shadowing, which returns the union of the declara-tions in two environments restricted so that if a variable x has any declarationsin the first environment, no declarations of x are included from the second envi-ronment. More formally:

Definition 1 (Shadowing). For any environments E1, E2, we write:E1 / E2 := E1 [ {xD

i

2 E2 | @ xDi

0 2 E1}

A Theory of Name Resolution with Extended Coverage and Proofs

18 TUD-SERG-2015-001

where

2

ED[I, S](S) :=

(

; if S 2 SD(S)

EP [I, S](S) :=

; if S 2 SEV [I, {S} [ S](P(S))

EI [I, S](S) :=

8

<

:

; if S 2 SS

n

EL[I, {S} [ S](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I, S](S) := ED[I, S](S) / EI [I, S](S)

EV [I, S](S) := EL[I, S](S) / EP [I, S](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I, ;](S)}

ED[I](S) := D(S)

EP [I](S) := EV [I](P(S))

EI [I](S) :=S

n

EL[I](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I](S) := ED[I](S) / EI [I](S)

EV [I](S) := EL[I](S) / EP [I](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I](S)}

ED(S) := D(S)

EP (S) := EV (P(S))

EI(S) :=S

n

EL(Sy) | yRi 2 I(S) ^ y

Dj :Sy 2 Resolve(yR

i )o

EL(S) := ED(S) / EI(S)

EV (S) := EL(S) / EP (S)

Resolve(xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV (S)}

• still need to incorporate “seen imports”

Resolution Algorithm v2

imperative language, explained here. The traversal is specified as a collection of(potentially) mutually recursive functions, one or more for each syntactic classof LM. Each function f is defined by a set of clauses [[pattern]]f

args

. When f isinvoked on a term, the clause whose pattern matches the term is executed. Func-tions may also take additional arguments args. Each clause body consists of asequence of statements separated by semicolons. Functions can optionally returna value using ret(). The let statement binds a metavariable in the remainder ofthe clause body. An empty clause body is written ().

The algorithm is initiated by invoking [[_]]prog on an entire LM program. Itsnet effect is to produce a scope graph via a sequence of imperative operations.The construct new

P

creates a new scope S with parent P (or no parent if p =?)and empty sets D(S), R(S), and I(S). These sets are subsequently populatedusing the += operator, which extends a set imperatively. The program scopegraph is simply the set of scopes that have been created and populated whenthe traversal terminates.

5 Resolution Algorithm

The calculus of Section 2 gives a precise definition of resolution. In principle, wecan search for derivations in the calculus to answer questions such as “Does thisvariable reference resolve to this declaration?” or “Which variable declarationsdoes this reference resolve to?” But automating this search process is not trivial,because of the need for back-tracking and because the paths in reachabilityderivations can have cycles (visiting the same scope more than once), and hencecan grow arbitrarily long.

In this section we describe a deterministic and terminating algorithm forcomputing resolutions, which provides a practical basis for implementing toolsbased on scope graphs, and prove that it is sound and complete with respectto the calculus. This algorithm also connects the calculus, which talks aboutresolution of a single variable at a time, to more conventional descriptions ofbinding which use “environments” or “contexts” to describe all the visible orreachable declarations accessible from a program location.

For us, an environment is just a set of declarations xDi

. This can be thoughtof as a function from identifiers to (possible empty) sets of declaration positions.(In this paper, we leave the representation of environments abstract; in practice,one would use a hash table or other dictionary data structure.) We construct anatomic environment corresponding to the declarations in each scope, and thencombine atomic environments to describe the sets of reachable and visible dec-larations resulting from the parent and import relations. The key operator forcombining environments is shadowing, which returns the union of the declara-tions in two environments restricted so that if a variable x has any declarationsin the first environment, no declarations of x are included from the second envi-ronment. More formally:

Definition 1 (Shadowing). For any environments E1, E2, we write:E1 / E2 := E1 [ {xD

i

2 E2 | @ xDi

0 2 E1}

A Theory of Name Resolution with Extended Coverage and Proofs

18 TUD-SERG-2015-001

where

2

ED[I, S](S) :=

(

; if S 2 SD(S)

EP [I, S](S) :=

; if S 2 SEV [I, {S} [ S](P(S))

EI [I, S](S) :=

8

<

:

; if S 2 SS

n

EL[I, {S} [ S](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I, S](S) := ED[I, S](S) / EI [I, S](S)

EV [I, S](S) := EL[I, S](S) / EP [I, S](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I, ;](S)}

ED[I](S) := D(S)

EP [I](S) := EV [I](P(S))

EI [I](S) :=S

n

EL[I](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I](S) := ED[I](S) / EI [I](S)

EV [I](S) := EL[I](S) / EP [I](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I](S)}

ED(S) := D(S)

EP (S) := EV (P(S))

EI(S) :=S

n

EL(Sy) | yRi 2 I(S) ^ y

Dj :Sy 2 Resolve(yR

i )o

EL(S) := ED(S) / EI(S)

EV (S) := EL(S) / EP (S)

Resolve(xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV (S)}

Resolution Algorithm v2

imperative language, explained here. The traversal is specified as a collection of(potentially) mutually recursive functions, one or more for each syntactic classof LM. Each function f is defined by a set of clauses [[pattern]]f

args

. When f isinvoked on a term, the clause whose pattern matches the term is executed. Func-tions may also take additional arguments args. Each clause body consists of asequence of statements separated by semicolons. Functions can optionally returna value using ret(). The let statement binds a metavariable in the remainder ofthe clause body. An empty clause body is written ().

The algorithm is initiated by invoking [[_]]prog on an entire LM program. Itsnet effect is to produce a scope graph via a sequence of imperative operations.The construct new

P

creates a new scope S with parent P (or no parent if p =?)and empty sets D(S), R(S), and I(S). These sets are subsequently populatedusing the += operator, which extends a set imperatively. The program scopegraph is simply the set of scopes that have been created and populated whenthe traversal terminates.

5 Resolution Algorithm

The calculus of Section 2 gives a precise definition of resolution. In principle, wecan search for derivations in the calculus to answer questions such as “Does thisvariable reference resolve to this declaration?” or “Which variable declarationsdoes this reference resolve to?” But automating this search process is not trivial,because of the need for back-tracking and because the paths in reachabilityderivations can have cycles (visiting the same scope more than once), and hencecan grow arbitrarily long.

In this section we describe a deterministic and terminating algorithm forcomputing resolutions, which provides a practical basis for implementing toolsbased on scope graphs, and prove that it is sound and complete with respectto the calculus. This algorithm also connects the calculus, which talks aboutresolution of a single variable at a time, to more conventional descriptions ofbinding which use “environments” or “contexts” to describe all the visible orreachable declarations accessible from a program location.

For us, an environment is just a set of declarations xDi

. This can be thoughtof as a function from identifiers to (possible empty) sets of declaration positions.(In this paper, we leave the representation of environments abstract; in practice,one would use a hash table or other dictionary data structure.) We construct anatomic environment corresponding to the declarations in each scope, and thencombine atomic environments to describe the sets of reachable and visible dec-larations resulting from the parent and import relations. The key operator forcombining environments is shadowing, which returns the union of the declara-tions in two environments restricted so that if a variable x has any declarationsin the first environment, no declarations of x are included from the second envi-ronment. More formally:

Definition 1 (Shadowing). For any environments E1, E2, we write:E1 / E2 := E1 [ {xD

i

2 E2 | @ xDi

0 2 E1}

A Theory of Name Resolution with Extended Coverage and Proofs

18 TUD-SERG-2015-001

where

2

ED[I, S](S) :=

(

; if S 2 SD(S)

EP [I, S](S) :=

; if S 2 SEV [I, {S} [ S](P(S))

EI [I, S](S) :=

8

<

:

; if S 2 SS

n

EL[I, {S} [ S](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I, S](S) := ED[I, S](S) / EI [I, S](S)

EV [I, S](S) := EL[I, S](S) / EP [I, S](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I, ;](S)}

ED[I](S) := D(S)

EP [I](S) := EV [I](P(S))

EI [I](S) :=S

n

EL[I](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I](S) := ED[I](S) / EI [I](S)

EV [I](S) := EL[I](S) / EP [I](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I](S)}

ED(S) := D(S)

EP (S) := EV (P(S))

EI(S) :=S

n

EL(Sy) | yRi 2 I(S) ^ y

Dj :Sy 2 Resolve(yR

i )o

EL(S) := ED(S) / EI(S)

EV (S) := EL(S) / EP (S)

Resolve(xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV (S)}

• but still might not terminate due to cycles (e.g. consider a scope that imports itself)

Resolution Algorithm v32

ED[I, S](S) :=

(

; if S 2 SD(S)

EP [I, S](S) :=

; if S 2 SEV [I, {S} [ S](P(S))

EI [I, S](S) :=

8

<

:

; if S 2 SS

n

EL[I, {S} [ S](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I, S](S) := ED[I, S](S) / EI [I, S](S)

EV [I, S](S) := EL[I, S](S) / EP [I, S](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I, ;](S)}

ED[I](S) := D(S)

EP [I](S) := EV [I](P(S))

EI [I](S) :=S

n

EL[I](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I](S) := ED[I](S) / EI [I](S)

EV [I](S) := EL[I](S) / EP [I](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I](S)}

ED(S) := D(S)

EP (S) := EV (P(S))

EI(S) :=S

n

EL(Sy) | yRi 2 I(S) ^ y

Dj :Sy 2 Resolve(yR

i )o

EL(S) := ED(S) / EI(S)

EV (S) := EL(S) / EP (S)

Resolve(xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV (S)}

Resolution Algorithm v3

Lemma: visibility paths never have cycles

2

ED[I, S](S) :=

(

; if S 2 SD(S)

EP [I, S](S) :=

; if S 2 SEV [I, {S} [ S](P(S))

EI [I, S](S) :=

8

<

:

; if S 2 SS

n

EL[I, {S} [ S](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I, S](S) := ED[I, S](S) / EI [I, S](S)

EV [I, S](S) := EL[I, S](S) / EP [I, S](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I, ;](S)}

ED[I](S) := D(S)

EP [I](S) := EV [I](P(S))

EI [I](S) :=S

n

EL[I](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I](S) := ED[I](S) / EI [I](S)

EV [I](S) := EL[I](S) / EP [I](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I](S)}

ED(S) := D(S)

EP (S) := EV (P(S))

EI(S) :=S

n

EL(Sy) | yRi 2 I(S) ^ y

Dj :Sy 2 Resolve(yR

i )o

EL(S) := ED(S) / EI(S)

EV (S) := EL(S) / EP (S)

Resolve(xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV (S)}

Resolution Algorithm v3

Res[I](xRi

) := {xDj

| 9S s.t. x

Ri

2 R(S) ^ x

Dj

2 EnvV

[{xRi

} [ I, ;](S)}Env

V

[I, S](S) := EnvL

[I, S](S) / EnvP

[I, S](S)Env

L

[I, S](S) := EnvD

[I, S](S) / EnvI

[I, S](S)

EnvD

[I, S](S) :=(

; if S 2 SD(S)

EnvI

[I, S](S) :=

8

<

:

; if S 2 SS

n

EnvL

[I, {S} [ S](Sy

) | yRi

2 I(S) \ I ^ y

Dj

:Sy

2 Res[I](yRi

)o

EnvP

[I, S](S) :=

; if S 2 SEnv

V

[I, {S} [ S](P(S))

Fig. 18. Resolution algorithm

Figure 18 specifies an algorithm Res[I](xRi

) for resolving a reference xRi

to a set ofcorresponding declarations xD

j

. Like the calculus, the algorithm avoids trying touse an import to resolve itself by maintaining a set I of “already seen” imports.The algorithm works by computing the full environment Env

V

[I, S](S) of decla-rations that are visible in the scope S containing xR

i

, and then extracting justthe declarations for x. The full environment, in turn, is built from the more basicenvironments Env

D

of immediate declarations, EnvI

of imported declarations,and Env

P

of lexically enclosing declarations, using the shadowing operator. Theorder of construction matches both the WF restriction from the calculus, whichprevents the use of parent after an import, and the path ordering <, whichprefers immediate declarations over imports and imports over declarations fromthe parent scope. (Note that the algorithm does not work for the variants of WFand < described in Section 2.5.) A key difference from the calculus is that theshadowing operator is applied at each stage in environment construction, ratherthan applying the visibility criterion just once at the “top level” as in calculusrule V . This difference is a natural consequence of the fact that the algorithmcomputes sets of declarations rather than full derivation paths, so it does notmaintain enough information to delay the visibility computation.

Termination The algorithm is terminating using the well-founded lexicographicmeasure (|R(G) \ I|, |S(G) \ S|). Termination is straightforward by unfolding thecalls to Res in Env

I

and then inlining the definitions of EnvV

and EnvL

: thisgives an equivalent algorithm in which the measure strictly decreases at everyrecursive call.

5.1 Correctness of Resolution Algorithm

The resolution algorithm is sound and complete with respect to the calculus.

Theorem 1. 8 I, xRi

, j, (xDj

2 Res[I](xRi

)) () (9p s.t. I ` p : xRi

7�! xDj

).

We sketch the proof of this theorem here; details of the supporting lemmasand proofs are in Appendix B. To begin with, we must deal with the fact that

A Theory of Name Resolution with Extended Coverage and Proofs

TUD-SERG-2015-001 19

Theorem: algorithm is sound and complete for calculus:

Lemma: visibility paths never have cycles

2

ED[I, S](S) :=

(

; if S 2 SD(S)

EP [I, S](S) :=

; if S 2 SEV [I, {S} [ S](P(S))

EI [I, S](S) :=

8

<

:

; if S 2 SS

n

EL[I, {S} [ S](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I, S](S) := ED[I, S](S) / EI [I, S](S)

EV [I, S](S) := EL[I, S](S) / EP [I, S](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I, ;](S)}

ED[I](S) := D(S)

EP [I](S) := EV [I](P(S))

EI [I](S) :=S

n

EL[I](Sy) | yRi 2 I(S) \ I ^ y

Dj :Sy 2 Resolve[I](yR

i )o

EL[I](S) := ED[I](S) / EI [I](S)

EV [I](S) := EL[I](S) / EP [I](S)

Resolve[I](xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV [{xR

i } [ I](S)}

ED(S) := D(S)

EP (S) := EV (P(S))

EI(S) :=S

n

EL(Sy) | yRi 2 I(S) ^ y

Dj :Sy 2 Resolve(yR

i )o

EL(S) := ED(S) / EI(S)

EV (S) := EL(S) / EP (S)

Resolve(xRi ) := {xD

j | 9S s.t. x

Ri 2 R(S) ^ x

Dj 2 EV (S)}

Language-independent 𝜶-equivalenceProgram similarity

24

5.1 ↵-Equivalence

We now define ↵-equivalence using scope graphs. Except for the leaves represent-ing identifiers, two ↵-equivalent programs must have the same abstract syntaxtree. We write P ' P’ (pronounced “P and P’ are similar”) when the ASTs of Pand P’ are equal up to identifiers. To compare two programs we first comparetheir AST structures; if these are equal then we compare how identifiers behavein these programs. Since two potentially ↵-equivalent programs are similar, theidentifiers occur at the same positions. In order to compare the identifiers’ behav-ior, we define equivalence classes of positions of identifiers in a program: positionsin the same equivalence class are declarations of or reference to the same entity.The abstract position x̄ identifies the equivalence class corresponding to the freevariable x.

Given a program P, we write P for the set of positions corresponding toreferences and declarations and PX for P extended with the artificial positions(e.g. x̄). We define the P⇠ equivalence relation between elements of PX as thereflexive symmetric and transitive closure of the resolution relation.

Definition 7 (Position equivalence).

` p : r i

x

7�! d i

0

x

iP⇠ i0

i0P⇠ i

iP⇠ i0

iP⇠ i0 i0

P⇠ i00

iP⇠ i00 i

P⇠ i

In this equivalence relation, the class containing the abstract free variable dec-laration can not contain any other declaration. So the references in a particularclass are either all free or all bound.

Lemma 6 (Free variable class). The equivalence class of a free variable doesnot contain any other declaration, i.e. 8 d i

x

s.t. iP⇠ x̄ =) i = x̄

Proof. Detailed proof is in appendix A.5, we first prove:8 r i

x

, (` > : r i

x

7�! d x̄

x

) =) 8 p d i

0

x

, p ` r i

x

7�! d i

0

x

=) i0 = x̄ ^ p = >and then proceed by induction on the equivalence relation.

The equivalence classes defined by this relation contain references to or declara-tions of the same entity. Given this relation, we can state that two program are↵-equivalent if the identifiers at identical positions refer to the same entity, thatis belong to the same equivalence class:

Definition 8 (↵-equivalence). Two programs P1 and P2 are ↵-equivalent (de-noted P1

↵⇡ P2) when they are similar and have the same ⇠-equivalence classes:

P1↵⇡ P2 , P1 ' P2 ^ 8 e e0, e

P1⇠ e0 , eP2⇠ e0

Remark 1.↵⇡ is an equivalence relation since ' and , are equivalence relations.

if have same AST ignoring identifier names

Language-independent 𝜶-equivalence

Position equivalence

24

5.1 ↵-Equivalence

We now define ↵-equivalence using scope graphs. Except for the leaves represent-ing identifiers, two ↵-equivalent programs must have the same abstract syntaxtree. We write P ' P’ (pronounced “P and P’ are similar”) when the ASTs of Pand P’ are equal up to identifiers. To compare two programs we first comparetheir AST structures; if these are equal then we compare how identifiers behavein these programs. Since two potentially ↵-equivalent programs are similar, theidentifiers occur at the same positions. In order to compare the identifiers’ behav-ior, we define equivalence classes of positions of identifiers in a program: positionsin the same equivalence class are declarations of or reference to the same entity.The abstract position x̄ identifies the equivalence class corresponding to the freevariable x.

Given a program P, we write P for the set of positions corresponding toreferences and declarations and PX for P extended with the artificial positions(e.g. x̄). We define the P⇠ equivalence relation between elements of PX as thereflexive symmetric and transitive closure of the resolution relation.

Definition 7 (Position equivalence).

` p : r i

x

7�! d i

0

x

iP⇠ i0

i0P⇠ i

iP⇠ i0

iP⇠ i0 i0

P⇠ i00

iP⇠ i00 i

P⇠ i

In this equivalence relation, the class containing the abstract free variable dec-laration can not contain any other declaration. So the references in a particularclass are either all free or all bound.

Lemma 6 (Free variable class). The equivalence class of a free variable doesnot contain any other declaration, i.e. 8 d i

x

s.t. iP⇠ x̄ =) i = x̄

Proof. Detailed proof is in appendix A.5, we first prove:8 r i

x

, (` > : r i

x

7�! d x̄

x

) =) 8 p d i

0

x

, p ` r i

x

7�! d i

0

x

=) i0 = x̄ ^ p = >and then proceed by induction on the equivalence relation.

The equivalence classes defined by this relation contain references to or declara-tions of the same entity. Given this relation, we can state that two program are↵-equivalent if the identifiers at identical positions refer to the same entity, thatis belong to the same equivalence class:

Definition 8 (↵-equivalence). Two programs P1 and P2 are ↵-equivalent (de-noted P1

↵⇡ P2) when they are similar and have the same ⇠-equivalence classes:

P1↵⇡ P2 , P1 ' P2 ^ 8 e e0, e

P1⇠ e0 , eP2⇠ e0

Remark 1.↵⇡ is an equivalence relation since ' and , are equivalence relations.

xi xi'

Program similarity

24

5.1 ↵-Equivalence

We now define ↵-equivalence using scope graphs. Except for the leaves represent-ing identifiers, two ↵-equivalent programs must have the same abstract syntaxtree. We write P ' P’ (pronounced “P and P’ are similar”) when the ASTs of Pand P’ are equal up to identifiers. To compare two programs we first comparetheir AST structures; if these are equal then we compare how identifiers behavein these programs. Since two potentially ↵-equivalent programs are similar, theidentifiers occur at the same positions. In order to compare the identifiers’ behav-ior, we define equivalence classes of positions of identifiers in a program: positionsin the same equivalence class are declarations of or reference to the same entity.The abstract position x̄ identifies the equivalence class corresponding to the freevariable x.

Given a program P, we write P for the set of positions corresponding toreferences and declarations and PX for P extended with the artificial positions(e.g. x̄). We define the P⇠ equivalence relation between elements of PX as thereflexive symmetric and transitive closure of the resolution relation.

Definition 7 (Position equivalence).

` p : r i

x

7�! d i

0

x

iP⇠ i0

i0P⇠ i

iP⇠ i0

iP⇠ i0 i0

P⇠ i00

iP⇠ i00 i

P⇠ i

In this equivalence relation, the class containing the abstract free variable dec-laration can not contain any other declaration. So the references in a particularclass are either all free or all bound.

Lemma 6 (Free variable class). The equivalence class of a free variable doesnot contain any other declaration, i.e. 8 d i

x

s.t. iP⇠ x̄ =) i = x̄

Proof. Detailed proof is in appendix A.5, we first prove:8 r i

x

, (` > : r i

x

7�! d x̄

x

) =) 8 p d i

0

x

, p ` r i

x

7�! d i

0

x

=) i0 = x̄ ^ p = >and then proceed by induction on the equivalence relation.

The equivalence classes defined by this relation contain references to or declara-tions of the same entity. Given this relation, we can state that two program are↵-equivalent if the identifiers at identical positions refer to the same entity, thatis belong to the same equivalence class:

Definition 8 (↵-equivalence). Two programs P1 and P2 are ↵-equivalent (de-noted P1

↵⇡ P2) when they are similar and have the same ⇠-equivalence classes:

P1↵⇡ P2 , P1 ' P2 ^ 8 e e0, e

P1⇠ e0 , eP2⇠ e0

Remark 1.↵⇡ is an equivalence relation since ' and , are equivalence relations.

if have same AST ignoring identifier names

Language-independent 𝜶-equivalence

Position equivalence

24

5.1 ↵-Equivalence

We now define ↵-equivalence using scope graphs. Except for the leaves represent-ing identifiers, two ↵-equivalent programs must have the same abstract syntaxtree. We write P ' P’ (pronounced “P and P’ are similar”) when the ASTs of Pand P’ are equal up to identifiers. To compare two programs we first comparetheir AST structures; if these are equal then we compare how identifiers behavein these programs. Since two potentially ↵-equivalent programs are similar, theidentifiers occur at the same positions. In order to compare the identifiers’ behav-ior, we define equivalence classes of positions of identifiers in a program: positionsin the same equivalence class are declarations of or reference to the same entity.The abstract position x̄ identifies the equivalence class corresponding to the freevariable x.

Given a program P, we write P for the set of positions corresponding toreferences and declarations and PX for P extended with the artificial positions(e.g. x̄). We define the P⇠ equivalence relation between elements of PX as thereflexive symmetric and transitive closure of the resolution relation.

Definition 7 (Position equivalence).

` p : r i

x

7�! d i

0

x

iP⇠ i0

i0P⇠ i

iP⇠ i0

iP⇠ i0 i0

P⇠ i00

iP⇠ i00 i

P⇠ i

In this equivalence relation, the class containing the abstract free variable dec-laration can not contain any other declaration. So the references in a particularclass are either all free or all bound.

Lemma 6 (Free variable class). The equivalence class of a free variable doesnot contain any other declaration, i.e. 8 d i

x

s.t. iP⇠ x̄ =) i = x̄

Proof. Detailed proof is in appendix A.5, we first prove:8 r i

x

, (` > : r i

x

7�! d x̄

x

) =) 8 p d i

0

x

, p ` r i

x

7�! d i

0

x

=) i0 = x̄ ^ p = >and then proceed by induction on the equivalence relation.

The equivalence classes defined by this relation contain references to or declara-tions of the same entity. Given this relation, we can state that two program are↵-equivalent if the identifiers at identical positions refer to the same entity, thatis belong to the same equivalence class:

Definition 8 (↵-equivalence). Two programs P1 and P2 are ↵-equivalent (de-noted P1

↵⇡ P2) when they are similar and have the same ⇠-equivalence classes:

P1↵⇡ P2 , P1 ' P2 ^ 8 e e0, e

P1⇠ e0 , eP2⇠ e0

Remark 1.↵⇡ is an equivalence relation since ' and , are equivalence relations.

xi xi'

Program similarity

24

5.1 ↵-Equivalence

We now define ↵-equivalence using scope graphs. Except for the leaves represent-ing identifiers, two ↵-equivalent programs must have the same abstract syntaxtree. We write P ' P’ (pronounced “P and P’ are similar”) when the ASTs of Pand P’ are equal up to identifiers. To compare two programs we first comparetheir AST structures; if these are equal then we compare how identifiers behavein these programs. Since two potentially ↵-equivalent programs are similar, theidentifiers occur at the same positions. In order to compare the identifiers’ behav-ior, we define equivalence classes of positions of identifiers in a program: positionsin the same equivalence class are declarations of or reference to the same entity.The abstract position x̄ identifies the equivalence class corresponding to the freevariable x.

Given a program P, we write P for the set of positions corresponding toreferences and declarations and PX for P extended with the artificial positions(e.g. x̄). We define the P⇠ equivalence relation between elements of PX as thereflexive symmetric and transitive closure of the resolution relation.

Definition 7 (Position equivalence).

` p : r i

x

7�! d i

0

x

iP⇠ i0

i0P⇠ i

iP⇠ i0

iP⇠ i0 i0

P⇠ i00

iP⇠ i00 i

P⇠ i

In this equivalence relation, the class containing the abstract free variable dec-laration can not contain any other declaration. So the references in a particularclass are either all free or all bound.

Lemma 6 (Free variable class). The equivalence class of a free variable doesnot contain any other declaration, i.e. 8 d i

x

s.t. iP⇠ x̄ =) i = x̄

Proof. Detailed proof is in appendix A.5, we first prove:8 r i

x

, (` > : r i

x

7�! d x̄

x

) =) 8 p d i

0

x

, p ` r i

x

7�! d i

0

x

=) i0 = x̄ ^ p = >and then proceed by induction on the equivalence relation.

The equivalence classes defined by this relation contain references to or declara-tions of the same entity. Given this relation, we can state that two program are↵-equivalent if the identifiers at identical positions refer to the same entity, thatis belong to the same equivalence class:

Definition 8 (↵-equivalence). Two programs P1 and P2 are ↵-equivalent (de-noted P1

↵⇡ P2) when they are similar and have the same ⇠-equivalence classes:

P1↵⇡ P2 , P1 ' P2 ^ 8 e e0, e

P1⇠ e0 , eP2⇠ e0

Remark 1.↵⇡ is an equivalence relation since ' and , are equivalence relations.

if have same AST ignoring identifier names

24

5.1 ↵-Equivalence

We now define ↵-equivalence using scope graphs. Except for the leaves represent-ing identifiers, two ↵-equivalent programs must have the same abstract syntaxtree. We write P ' P’ (pronounced “P and P’ are similar”) when the ASTs of Pand P’ are equal up to identifiers. To compare two programs we first comparetheir AST structures; if these are equal then we compare how identifiers behavein these programs. Since two potentially ↵-equivalent programs are similar, theidentifiers occur at the same positions. In order to compare the identifiers’ behav-ior, we define equivalence classes of positions of identifiers in a program: positionsin the same equivalence class are declarations of or reference to the same entity.The abstract position x̄ identifies the equivalence class corresponding to the freevariable x.

Given a program P, we write P for the set of positions corresponding toreferences and declarations and PX for P extended with the artificial positions(e.g. x̄). We define the P⇠ equivalence relation between elements of PX as thereflexive symmetric and transitive closure of the resolution relation.

Definition 7 (Position equivalence).

` p : r i

x

7�! d i

0

x

iP⇠ i0

i0P⇠ i

iP⇠ i0

iP⇠ i0 i0

P⇠ i00

iP⇠ i00 i

P⇠ i

In this equivalence relation, the class containing the abstract free variable dec-laration can not contain any other declaration. So the references in a particularclass are either all free or all bound.

Lemma 6 (Free variable class). The equivalence class of a free variable doesnot contain any other declaration, i.e. 8 d i

x

s.t. iP⇠ x̄ =) i = x̄

Proof. Detailed proof is in appendix A.5, we first prove:8 r i

x

, (` > : r i

x

7�! d x̄

x

) =) 8 p d i

0

x

, p ` r i

x

7�! d i

0

x

=) i0 = x̄ ^ p = >and then proceed by induction on the equivalence relation.

The equivalence classes defined by this relation contain references to or declara-tions of the same entity. Given this relation, we can state that two program are↵-equivalent if the identifiers at identical positions refer to the same entity, thatis belong to the same equivalence class:

Definition 8 (↵-equivalence). Two programs P1 and P2 are ↵-equivalent (de-noted P1

↵⇡ P2) when they are similar and have the same ⇠-equivalence classes:

P1↵⇡ P2 , P1 ' P2 ^ 8 e e0, e

P1⇠ e0 , eP2⇠ e0

Remark 1.↵⇡ is an equivalence relation since ' and , are equivalence relations.(with some further details about free variables)

Alpha equivalence

25

module A1 {

def x2 := 1

}

module B3 {

def x4 := 2

}

module C5 {

import A6 B7;

def y8 := x9

}

module D10 {

import A11;

def y12 := x13

}

module E14 {

import B15;

def y16 := x17

}

P1

module AA1 {

def z2 := 1

}

module BB3 {

def z4 := 2

}

module C5 {

import AA6 BB7;

def s8 := z9

}

module D10 {

import AA11;

def u12 := z13

}

module E14 {

import BB15;

def v16 := z17

}

P2

module A1 {

def z2 := 1

}

module B3 {

def x4 := 2

}

module C5 {

import A6 B7;

def y8 := z9

}

module D10 {

import A11;

def y12 := z13

}

module E14 {

import B15;

def y16 := x17

}

P3

Fig. 23. ↵-equivalence and duplicate declaration

5.2 The

↵⇡ Relation

Free variables. The P⇠ equivalence classes corresponding to free variables x alsocontains the artificial position x̄. Since the equivalence classes of two equivalentprograms P1 and P2 have to be exactly the same, every element equivalent tox̄ (i.e. a free reference) in P1 is also equivalent to x̄ in P2. Therefore the freereferences of ↵-equivalent programs have to be identical.

Duplicate declarations. The definition allows us to also capture ↵-equivalenceof programs with duplicate declarations. For example, in the program P1 inFigure 20, x9 has a duplicate declaration (it can resolve to x2 through A1 or tox4 through B3) whereas x13 simply resolves to x2 and x17 to x4 . Thus positions2, 4, 9, 13, and 17 are in the same equivalence class. (Similarly, positions 1,6,and 11 form an equivalence class refering to module A and positions 3,7, and15 form an equivalence class refering to module B , while positions 8, 12, and 16each form singleton equivalence classes.) The program P2 is ↵-equivalent to P1:all members of each equivalence class have been consistently renamed. Howeverthe program P3, where only the first declaration of x and its direct referencesare renamed into z , is not ↵-equivalent to P1, z9 now only resolves to z2 thusthis program does not contain the initial ambiguity of P1.

5.3 Renaming

Renaming is the substitution of a bound variable by a new variable throughoutthe program. It has several practical applications such as rename refactoring inan IDE, transformation to program with unique identifiers, or as an intermediatetransformation when implementing capture-avoiding substitution.

P1

24

5.1 ↵-Equivalence

We now define ↵-equivalence using scope graphs. Except for the leaves represent-ing identifiers, two ↵-equivalent programs must have the same abstract syntaxtree. We write P ' P’ (pronounced “P and P’ are similar”) when the ASTs of Pand P’ are equal up to identifiers. To compare two programs we first comparetheir AST structures; if these are equal then we compare how identifiers behavein these programs. Since two potentially ↵-equivalent programs are similar, theidentifiers occur at the same positions. In order to compare the identifiers’ behav-ior, we define equivalence classes of positions of identifiers in a program: positionsin the same equivalence class are declarations of or reference to the same entity.The abstract position x̄ identifies the equivalence class corresponding to the freevariable x.

Given a program P, we write P for the set of positions corresponding toreferences and declarations and PX for P extended with the artificial positions(e.g. x̄). We define the P⇠ equivalence relation between elements of PX as thereflexive symmetric and transitive closure of the resolution relation.

Definition 7 (Position equivalence).

` p : r i

x

7�! d i

0

x

iP⇠ i0

i0P⇠ i

iP⇠ i0

iP⇠ i0 i0

P⇠ i00

iP⇠ i00 i

P⇠ i

In this equivalence relation, the class containing the abstract free variable dec-laration can not contain any other declaration. So the references in a particularclass are either all free or all bound.

Lemma 6 (Free variable class). The equivalence class of a free variable doesnot contain any other declaration, i.e. 8 d i

x

s.t. iP⇠ x̄ =) i = x̄

Proof. Detailed proof is in appendix A.5, we first prove:8 r i

x

, (` > : r i

x

7�! d x̄

x

) =) 8 p d i

0

x

, p ` r i

x

7�! d i

0

x

=) i0 = x̄ ^ p = >and then proceed by induction on the equivalence relation.

The equivalence classes defined by this relation contain references to or declara-tions of the same entity. Given this relation, we can state that two program are↵-equivalent if the identifiers at identical positions refer to the same entity, thatis belong to the same equivalence class:

Definition 8 (↵-equivalence). Two programs P1 and P2 are ↵-equivalent (de-noted P1

↵⇡ P2) when they are similar and have the same ⇠-equivalence classes:

P1↵⇡ P2 , P1 ' P2 ^ 8 e e0, e

P1⇠ e0 , eP2⇠ e0

Remark 1.↵⇡ is an equivalence relation since ' and , are equivalence relations.

P2 P2

24

5.1 ↵-Equivalence

We now define ↵-equivalence using scope graphs. Except for the leaves represent-ing identifiers, two ↵-equivalent programs must have the same abstract syntaxtree. We write P ' P’ (pronounced “P and P’ are similar”) when the ASTs of Pand P’ are equal up to identifiers. To compare two programs we first comparetheir AST structures; if these are equal then we compare how identifiers behavein these programs. Since two potentially ↵-equivalent programs are similar, theidentifiers occur at the same positions. In order to compare the identifiers’ behav-ior, we define equivalence classes of positions of identifiers in a program: positionsin the same equivalence class are declarations of or reference to the same entity.The abstract position x̄ identifies the equivalence class corresponding to the freevariable x.

Given a program P, we write P for the set of positions corresponding toreferences and declarations and PX for P extended with the artificial positions(e.g. x̄). We define the P⇠ equivalence relation between elements of PX as thereflexive symmetric and transitive closure of the resolution relation.

Definition 7 (Position equivalence).

` p : r i

x

7�! d i

0

x

iP⇠ i0

i0P⇠ i

iP⇠ i0

iP⇠ i0 i0

P⇠ i00

iP⇠ i00 i

P⇠ i

In this equivalence relation, the class containing the abstract free variable dec-laration can not contain any other declaration. So the references in a particularclass are either all free or all bound.

Lemma 6 (Free variable class). The equivalence class of a free variable doesnot contain any other declaration, i.e. 8 d i

x

s.t. iP⇠ x̄ =) i = x̄

Proof. Detailed proof is in appendix A.5, we first prove:8 r i

x

, (` > : r i

x

7�! d x̄

x

) =) 8 p d i

0

x

, p ` r i

x

7�! d i

0

x

=) i0 = x̄ ^ p = >and then proceed by induction on the equivalence relation.

The equivalence classes defined by this relation contain references to or declara-tions of the same entity. Given this relation, we can state that two program are↵-equivalent if the identifiers at identical positions refer to the same entity, thatis belong to the same equivalence class:

Definition 8 (↵-equivalence). Two programs P1 and P2 are ↵-equivalent (de-noted P1

↵⇡ P2) when they are similar and have the same ⇠-equivalence classes:

P1↵⇡ P2 , P1 ' P2 ^ 8 e e0, e

P1⇠ e0 , eP2⇠ e0

Remark 1.↵⇡ is an equivalence relation since ' and , are equivalence relations.

P3

Preserving ambiguity

Applying Scope Graphs

(ongoing work)

Validation

• We have modeled a large set of example binding patterns

- definition before use - different let binding flavors - recursive modules - imports and includes - qualified names - class inheritance - partial classes - …

Validation

• We have modeled a large set of example binding patterns

- definition before use - different let binding flavors - recursive modules - imports and includes - qualified names - class inheritance - partial classes - …

Validation

• Next goal: fully model some real languages - Java - ML - …

Generating Scope Graphs from AST

[[ds]]prog := P (S) := ? ^ [[ds]]decl⇤

S (new S)

[[moduleXi {ds}]]decls := X

Di :S

0 2 D(s) ^ P (S0) := s ^ [[ds]]decl⇤

S0 (new S

0)

[[import Xs.Xi]]decl

s := X

Ri 2 I(s) ^ [[Xs.Xi]]

qid

s

[[def b]]decls := [[b]]binds,s

[[xi = e]]bindsr,sd := x

Di 2 D(sd) ^ [[e]]expsr

[[xi]]qid

s := x

Ri 2 R(s)

[[fun (xi:t){e}]]exps := P (S0) := s ^ x

Di 2 D(S0) ^ [[e]]expS0 (new S

0)

[[letrec bs in e]]exps := P (S0) := s ^ [[bs]]bind⇤

S0,S0 ^ [[e]]expS0 (new S

0)

[[letpar bs in e]]exps := P (S0) := s ^ [[bs]]bind⇤

S,S0 ^ [[e]]expS0 (new S

0)

[[Xs.xi]]exp

s := [[Xs.xi]]qid

s

[[e1 e2]]exp

s := [[e1]]exp

s ^ [[e2]]exp

s

Authors: Hendrik van Antwerpen, Pierre Neron, Andrew Tolmach, Eelco Visser, GuidoWachsmuth

2 2015/6/3

generate smallest graph satisfying constraints

Binding gives TypesStatic type-checking (or inference) is one obvious client for name resolution

In many cases, we can perform resolution before doing type analysis

def x : int = 6

def f = fun (y : int) { x + y }

def x : int = 6

def f = fun (y : int) { x + y }

def x : int = 6

def f = fun (y : int) { x + y }

Binding gives TypesStatic type-checking (or inference) is one obvious client for name resolution

In many cases, we can perform resolution before doing type analysis

def x : int = 6

def f = fun (y : int) { x + y }

def x : int = 6

def f = fun (y : int) { x + y }

def x : int = 6

def f = fun (y : int) { x + y }

Binding gives TypesStatic type-checking (or inference) is one obvious client for name resolution

In many cases, we can perform resolution before doing type analysis

def x : int = 6

def f = fun (y : int) { x + y }

def x : int = 6

def f = fun (y : int) { x + y }

def x : int = 6

def f = fun (y : int) { x + y }

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Types give BindingBut sometimes we need types before we can do name resolution

record A1 { x1 : int } record B1 { a1 : A2 ; x2 : bool}

def z1 : B2 = ...

def y1 = z2.x3

def y2 = z3.a2.x4

Our approach: interleave partial name resolution with type resolution (also using constraints)

Also in the works...

Also in the works...

• Scope graph semantics for binding specification languages (starting with NaBL)

Also in the works...

• Scope graph semantics for binding specification languages (starting with NaBL)

• Resolution-sensitive program transformations (e.g. renaming, refactoring)

Also in the works...

• Scope graph semantics for binding specification languages (starting with NaBL)

• Resolution-sensitive program transformations (e.g. renaming, refactoring)

• Dynamic analogs to static scope graphs

Also in the works...

Use Scope Graphs toDescribe Name Resolution

Use Scope Graphs toDescribe Name Resolution !!