Working on the release of 0.17, I came accross issue

http://bugs.strategoxt.org/browse/STR-672

strc: fix multiple external definitions problems

[strc | warning ] multiple external definitions with same signature
[ExtSDef(“TEMP”,[],[]),ExtSDef(“TEMP”,[],[])]

>From the names of the strategies I guessed that these are congruence
definitions. While proper strategy definitions that are imported as
externals are not exported as externals from a library (as per August
2006), constructors imported by a library, are also exported by that
library. This causes congruences to be regenerated, possibly not in that
same library, but in a library one step further in the import chain.

Thus, the external definitions for congruences from an imported library,
prevent generation of new congruences. However, since imported external
definitions are not exported, the next library does not see those
congruence definitions, and will re-generate them; giving rise to the
warning above when the external definition for this new congruence is
imported in another application or library.

I have tried out some schemes for solving this problem. What I have now
arrived at is treating constructors in the same way as strategy
definitions.

There is now a notion of “external” constructor declarations. Syntax:

external Foo : A * B -> C

These external constructor declarations are exported by a library along
with the external definitions for the strategies in the library. Thus,
importing libraries and programs can use these constructors in rules
and strategies.

However, external constructors are not exported from an importing
library. Just like external definitions are not exported from an
importing library. This entails that a third library that imports the
second, does not get the constructor declarations of the first. In order
to use those, the first library needs to be imported explicitly. Here is
an example:

Library A
—————–
module A
constructors
Foo : A
—————–>
module libA
constructors
external Foo : A
—————–

Library B
—————–
module B
imports libA
strategies
bar = !Foo()
// constructor Foo is available through libA import
—————–>
module libB
strategies
external bar
// only strategy bar is exported, not constructor Foo
—————–

Library or Application C
—————–
module C
imports libB
strategies
baz = !Foo(); …; bar
// error! libB does not export constructor Foo
——————

Library or Application C // corrected
—————–
module C
imports libB libA
strategies
baz = !Foo(); …; bar
// Foo is imported through libA
——————

I think this design makes sense (and should have done a long time ago).

The downside is that this change will break existing code; explicit
imports of indirectly imported libraries is needed.

My guess is that this will not be too bad in practice. Typically if the
constructors of a library are used, also its strategies will be used.
And for those it was already necessary to make an explicit import.

Submitted on 14 April 2008 at 10:22

On 14 April 2008 at 10:22 Jira commented:

STR-751, visser:
implemented

Log in to post comments