Revision 8a57f3b03992351f46c4537fd0d9351592278d2b (click the page title to view the current version)

Name Resolver Specification

Introduction

The goal of the name resolver in the Clafer compiler is to determine which clafer in the model is referred to by a given reference by name. In a Clafer model, names can repeat as each clafer declaration includes a new namespace. For example, there can be many clafers called X in various places in the model. The clafer X can be referred to in these two ways:

  1. as a super clafer: a : X (done in ResolveInheritance.hs), a -> X, and a ->> X (ResolveName.hs), and
  2. inside expressions in constraints and goals: [ some X ], X + 1, and << max sum X.ref >>.

The name resolver decides which of the potentially multiple Xs is being referred to. Clafer X can be resolved as

  • Special – this, parent, children, ref
  • TypeSpecial – primitive type: integer, string, (need to add real, natural, etc.)
  • Binding – local variable (in constraints with quantifier)
  • Subclafers – in descendants (BFS)+ inheritance
  • Reference – same as Subclafers + reachable via references
  • Ancestor – in ancestors
  • AbsClafer – abstract , top-level clafer
  • TopClafer – concrete, top-level clafer

Currently (Clafer 0.3.3), the name resolver applies the following sequence of resolution strategies (in that exact order) given the current environment env and the clafer’s id:

resolve env id [resolveSpecial, resolveBind, resolveDescendants, resolveAncestor pos, resolveTopLevel pos, resolveNone pos]

The strategy resolveNone reports an error that the clafer with the given id was not found.

Test Cases

Resolving Special

  • this refers to S1
S1
[ this ]
  • parent refers to S2
S2
a
[ parent ]
  • children refers to a ++ b
S3
   a
   b
   [ children ]

results in resolver: unknown uid 'children'

Resolving TypeSpecial

  • integer, string, real resolve to primitive types
age -> integer
age2 -> int
name -> string
interestRate -> real
interestRate -> double

results in resolver: real not found within and resolver: double not found within

Resolving Binding

  • b in b.c resolves to b in b : B1. c in b.c resolves to B1.c via inheritance.
abstract B1
c ?
[ all b : B1 | b.c ]
[ all disj b1; b2 : B1 | b1.c && b2.c ]
[ some b : B1 | b.c ]
[ no b : B1 | b.c ]

Resolving Subclafers

  • b in some b resolves to a.b and not to a.b.b
Sub
[ some b ]
a ?
b ?
b ?

Resolving Reference

  • a in some a should resolve to A5.a
A5 *
a *
refA5 ->> A5
[ some this.a ]
  • B in -> A.B should resolve to A.B
refAB -> A.B *
  [ some B ]

results in an error B not found

Resolving Ancestor

  • A1 in some A1 resolves to the top-level A1
A1 ?
B
[ some A1 ]
  • A2 in some A2 resolves to A2.A2 and not the top-level A2
A2 ?
  A2 ?
    B 
      [ some A2 ]

results in an unexplained compilation error.

Resolving AbsClafer

  • Abs in : Abs, -> Abs, and ->> Abs resolves to abstract Abs
abstract Abs
AbsColon : Abs
AbsSet -> Abs
AbsMultiSet ->> Abs
  • nested abstract
abstract Year
abstract Month
y2013 : Year
month : Month 12

Resolving TopClafer

  • T in some T resolves to T ?
T ?
[ some T ]
// this is not allowed - improper nesting

// myMonth : Month

Resolving Redefinition

  • (this affects name resolution for inheritance)
abstract A
	d 0..1

/* redefines A.d, narrows cardinality */

abstract B : A
	d 1..1 
		b ?

refA -> A

[ refA.ref.d.b ] this should produce error 'b' not found

refB -> B

[ refB.ref.d.b ] // this should work

Related BugBot Issues

Issues 48 and 65 are just proposals, we have not decided yet.