format: text

text:
# Phase transitions in two-dimensional anisotropic quantum magnets

## 1 Introduction

In this paper we examine the class of magnetic models described by the Hamiltonian

$$\widehat{}=J\underset{<\mathrm{𝐢𝐣}>}{}\left[\mu \left(\widehat{S}_𝐢^x\widehat{S}_𝐣^x+\widehat{S}_𝐢^y\widehat{S}_𝐣^y\right)+\lambda \widehat{S}_𝐢^z\widehat{S}_𝐣^z\right]$$
(1)
where $`𝐢(i_1,i_2)`$, $`𝐣(j_1,j_2)`$ are sites on a square lattice, and the sum runs over the pairs of nearest neighbours; the spin degrees of freedom are described by the quantum operators $`\widehat{𝐒}_𝐢(\widehat{S}_𝐢^x,\widehat{S}_𝐢^y,\widehat{S}_𝐢^z)`$, obeying the angular momentum commutation relations $`[\widehat{S}_𝐢^\alpha ,\widehat{S}_𝐣^\beta ]=ϵ^{\alpha \beta \gamma }\delta _{\mathrm{𝐢𝐣}}\widehat{S}_𝐢^\gamma `$ with $`|\widehat{𝐒}|^2=S(S+1)`$.

For positive $`\lambda `$ and $`\mu `$, the sign of the exchange integral $`J`$ sets the ferro- or antiferromagnetic character of the model, $`J>0`$ or $`J<0`$ respectively; for the sake of a more compact notation, however, we will hereafter take a positive $`J`$ and properly change the sign of $`\mu `$ and $`\lambda `$ to obtain the required antiferromagnetic Hamiltonian.

At a classical level, i.e. when $`S\mathrm{}`$, ferro- and antiferromagnets have the same static properties and can be simultaneously studied as far as their thermodynamics is concerned. On the other hand, when quantum fluctuations are taken into account, the two types of models display substantially different features. It is worthwhile noticing that, despite displaying the most interesting quantum features, antiferromagnetic models are less affected by quantum fluctuations than ferromagnetic ones, as quantum renormalizations are sensibly stronger in the latter, whatever the approach used to evaluate them.

In this paper, the anisotropy parameters $`\mu `$ and $`\lambda `$ are set to range in the interval $`[1,1]`$, and the following sub-classes of models are hence considered:

(i) Isotropic: $`\mu =\lambda `$, $`|\lambda |=1`$, ferro- and antiferromagnetic ($`\lambda >0`$ and $`\lambda <0`$, respectively).

(ii) Easy-plane: $`\mu =1`$, $`\lambda (1,1)`$, ferro- and antiferromagnetic ($`\lambda >0`$ and $`\lambda <0`$, respectively).

(iii) Easy-axis: $`\mu (1,1)`$, $`\lambda =\mathrm{sign}(\mu )`$, ferro- and antiferromagnetic ($`\mu >0`$ and $`\mu <0`$, respectively).

Models belonging to these sub-classes have the common feature of displaying, as the temperature decreases, a phase-transition towards a more ordered phase; this transition generically occurs at a critical temperature which is a function of both the spin value and the anisotropy parameters, and will be hereafter indicated by $`t_\mathrm{c}(\nu ,S)`$, with $`\nu =\mu ,\lambda `$ depending on the specific class considered, and the reduced temperature $`t`$ defined by $`tT/J\stackrel{~}{S}^2`$ with $`\stackrel{~}{S}S+1/2`$.

(i) The isotropic model, both ferro- and antiferromagnetic, has the full rotational $`O(3)`$ symmetry and it is hence in a paramagnetic phase down to $`t=0`$, as required by the Mermin-Wagner theorem MerminW66 . Its ground state, however and at variance with the one-dimensional case, is ordered for all spin values also in the antiferromagnetic case Manousakis91 , and the model can hence be thought to have a phase transition at a critical temperature $`t_\mathrm{c}(\pm 1,S)=0`$ $`S`$.

(ii) In the easy plane case, the Mermin-Wagner theorem still holds and no finite temperature transition towards a phase with a finite order parameter, may occur. However, a Berezinskii-Kosterlitz-Thouless (BKT) transition Berezinskii70 ; KosterlitzT73 , related with the existence of vortex-like topological excitations, is known to characterize the class of the easy-plane models and may occur at a critical temperature $`t_{\mathrm{BKT}}(\lambda ,S)>0`$.

The reference system for the easy-plane class is the planar, or $`XY`$, model, defined by Eq.(1) with $`\lambda =0`$, $`\mu =1`$. Its BKT critical temperature has been seen to be finite for all spin values: above $`t_{\mathrm{BKT}}`$ the system is disordered, with exponentially decaying correlation functions. In the whole region $`0<t<t_{\mathrm{BKT}}`$ the system is in a critical phase with vanishing magnetization: its correlation functions decay according to a power law, testifying to the existence of quasi-long-range order; at $`t=0`$ the magnetization gets a finite value and the system is ordered. The $`XY`$ model may be thought to display two phase-transitions: a BKT one at a finite temperature, followed by one towards a fully ordered phase at $`t=0`$.

(iii) In the easy-axis case, the Mermin-Wagner theorem does not hold, and the easy-axis models may undergo a transition of the Ising (I) type towards a phase with long-range order, at a critical temperature $`t_\mathrm{I}(\mu ,S)>0`$.

The reference system for this class of models will be hereafter called the $`Z`$ model, described by Eq.(1) with $`\mu =0`$, $`\lambda =1`$; such model has a transition temperature $`t_\mathrm{I}(0,S)>0`$ for all spin values. Above $`t_\mathrm{I}`$ the system is in a paramagnetic phase, with exponentially decaying correlation functions; below $`t_\mathrm{I}`$ the system is ordered with a finite magnetization along the easy axis. The $`Z`$ model with $`S=1/2`$ is the Ising model, representing an important source of information for the whole class of the easy-axis models, not only because of the existing exact results by Onsager Onsager44 , but also because of its fundamental role in the renormalization-group approach and in conformal field theory.

The information on the reference models, as well as the general considerations based on the symmetries of the Hamiltonian, are surely valuable, but not sufficient to fully appreciate the richness of features contained in Eq.(1), and to properly understand the thermodynamic and critical behaviour of the many existing real compounds whose magnetic behaviour is described by such Hamiltonian. To accomplish this goal one has to study how the specific values of $`\lambda `$, $`\mu `$, and $`S`$ may determine the behaviour of the system.

At a qualitative level, we know that quantum fluctuations, whose strength is measured by the quantum coupling $`1/S`$, introduce a disordering agent in the classical ($`S\mathrm{}`$) picture: as a consequence, we expect the possible critical temperatures to decrease with decreasing $`S`$. The same effect is obtained by increasing $`|\lambda |`$ (easy-plane case), or $`|\mu |`$ (easy-axis case): this in fact means to weaken the anisotropic character of the system, thus allowing larger spin fluctuations out of the easy plane or the easy axis, and inducing a lowering of the critical temperature. To this respect it is to be noticed that most real compounds have very weak anisotropies ArtsDW90 , i.e. values of $`\lambda `$ or $`\mu `$ very close to unity: this is the region where quantitative predictions are more difficult to obtain, as the model’s character is not well defined and fluctuations are large.

Aim of this paper is to provide a quantitative description of the model (1) when $`S`$ and $`\lambda `$, or $`\mu `$, are varied. We will mainly concentrate on the values of the critical temperatures, but also give expressions and results for other thermodynamic quantities. The method used is the pure-quantum self-consistent harmonic approximation (PQSCHA), extensively described in Ref. CTVV92  and already applied to many magnetic systems (see for instance Refs. CTVVprb92 ; CTVV97 ). Its implementation is markedly different depending on the specific class of models considered, as explained in Section 2, and the easy-plane and easy-axis cases will be hence considered separately (in Section 3 and 4, respectively). In Section 5 we will comment on the resulting global picture and compare our results with all the available experimental and numerical simulation data. Conclusions about the critical behaviour of the models will be finally drawn in Section 6.

## 2 Method and spin-boson transformations

The PQSCHA is a semiclassical method based on the path-integral formulation of quantum statistical mechanics: the main peculiarity of the method is that of defining an analytical separation between classical and pure-quantum contributions to the thermodynamics of the system CGTVV95 , thus allowing the possible exact treatment of the former, while requiring a self-consistent harmonic approximation of the latter. This means that the only approximated contribution is the non-linear pure-quantum one, which is in fact considered at the one-loop level. The value of such result is evident if one considers that most of the peculiar features of magnetic systems, including their critical behaviour, are determined by long-wavelength excitations, whose character is essentially classical; the possibility to fully take into account their non-linearity at the classical level, together with the fact that harmonic pure-quantum fluctuations are exactly considered, justifies the success of the PQSCHA in predicting most thermodynamic properties of magnetic systems in a large temperature range.

Without going into the details of the derivation of the PQSCHA, we report here the essential formulas, and discuss the scheme of implementation to magnetic systems, where differences between the sub-classes of models become essential.

Consider a quantum spin system on a lattice described by the Hamiltonian $`\widehat{}(\underset{¯}{\overset{^}{𝐒}})`$ with $`\underset{¯}{\overset{^}{𝐒}}(\widehat{𝐒}_1,\mathrm{}\widehat{𝐒}_N)`$ and $`N`$ number of lattice sites; if $`\widehat{O}`$ is the quantum operator relative to a physical observable of the system, the PQSCHA expression of its quantum statistical average has the classical-like form

$$\widehat{O}=\frac{1}{𝒵_{\mathrm{eff}}}d^N𝐬O_{\mathrm{eff}}(\underset{¯}{𝐬})e^{\beta _{\mathrm{eff}}\left(\underset{¯}{𝐬}\right)}$$
(2)
where $`\beta =t^1`$, $`𝒵_{\mathrm{eff}}=d^N𝐬e^{\beta _{\mathrm{eff}}}`$, and $`\underset{¯}{𝐬}(𝐬_1,\mathrm{}𝐬_N)`$ with $`𝐬_i`$ classical unit vectors. The effective Hamiltonian $`_{\mathrm{eff}}(\underset{¯}{𝐬};t,S)`$, is a classical-like function, depending on the parameters of the original Hamiltonian, and determined by the PQSCHA renormalization procedure; a similar procedure, when applied to the quantum operator $`\widehat{O}`$, leads to the function $`𝒪_{\mathrm{eff}}(\underset{¯}{𝐬};t,S)`$

The phase-space integral in Eq. (2) may be evaluated by any classical technique, such as the classical Monte Carlo (MC) simulation. Eq. (2), on the other hand, contains quantum renormalizations embodied in the temperature and spin dependence of $`_{\mathrm{eff}}`$ and $`𝒪_{\mathrm{eff}}`$; such dependence causes the effective classical model to change for each temperature point, so that ad hoc simulations must be performed, and only in very peculiar cases one can directly use existing MC data (see for instance the case of the isotropic model in Ref. CTVV97 ).

The PQSCHA naturally applies to bosonic systems, whose Hamiltonian is written in terms of conjugate operators $`\underset{¯}{\overset{^}{q}}(\widehat{q}_1,\mathrm{}\widehat{q}_N)`$, $`\underset{¯}{\overset{^}{p}}(\widehat{p}_1,\mathrm{}\widehat{p}_N)`$ such that $`[\widehat{q}_m,\widehat{p}_n]=i\delta _{mn}`$; the method, however, does not require $`\widehat{}(\underset{¯}{\overset{^}{p}},\underset{¯}{\overset{^}{q}})`$ to be standard, i.e. with separate quadratic kinetic $`\underset{¯}{\overset{^}{p}}`$-dependent and potential $`\underset{¯}{\overset{^}{q}}`$-dependent terms, and its application may be extended also to magnetic systems, according to the following scheme CGTVV95 : The spin Hamiltonian $`\widehat{}(\underset{¯}{𝐒})`$ is mapped to $`\widehat{}(\underset{¯}{\overset{^}{p}},\underset{¯}{\overset{^}{q}})`$ by a suitable spin-boson transformation; once the corresponding Weyl symbol $`(\underset{¯}{p},\underset{¯}{q})`$, with $`\underset{¯}{p}(p_1,\mathrm{}p_N)`$ and $`\underset{¯}{q}(q_1,\mathrm{}q_N)`$ classical phase-space variables, has been determined Weyl50 , the PQSCHA renormalizations may be evaluated and $`_{\mathrm{eff}}(\underset{¯}{p},\underset{¯}{q})`$ and $`𝒪_{\mathrm{eff}}(\underset{¯}{p},\underset{¯}{q})`$ follow. Finally $`_{\mathrm{eff}}(\underset{¯}{𝐬})`$ and $`𝒪_{\mathrm{eff}}(\underset{¯}{𝐬})`$ are constructed by the inverse of the classical analogue of the spin-boson transformation used at the beginning.

In order to succesfully carry out such renormalization scheme, the Weyl symbol of the bosonic Hamiltonian must be a well-behaved function in the whole phase space. Spin-boson transformations, on the other hand, can introduce singularities as a consequence of the topological impossibility of a global mapping of a spherical phase space into a flat one. The choice of the transformation must then be such that the singularities occur for configurations which are not thermodynamically relevant, and whose contribution may be hence approximated. Most of the methods for studying magnetic systems do in fact share this problem with the PQSCHA; what makes the difference is that by using the PQSCHA one separates the classical from the pure-quantum contribution to the thermal fluctuations, and the approximation only regards the latter, being the former exactly taken into account when the effective Hamiltonian is cast in the form of a classical spin Hamiltonian.

The spin-boson transformation which constitutes the first step of the magnetic PQSCHA is chosen according to the symmetry properties of the original Hamiltonian and of its ground state.

In markedly easy-plane cases ($`|\lambda |1`$) we use, for each spin operator, the Villain transformation (VT) Villain74

$$\widehat{S}^+=e^{i\widehat{q}}\sqrt{\stackrel{~}{S}^2\left(\widehat{p}+\frac{1}{2}\right)^2},\widehat{S}^{}=(\widehat{S}^+)^{},\widehat{S}^z=\widehat{p};$$
(3)
this transformation keeps the $`O(2)`$ symmetry in the easy plane, meanwhile allowing to deal with the square root in terms of a physically sound small-$`\widehat{p}`$ approximation.

In the easy-axis case, it makes no sense to use Eqs.(3), as the expectation value of the $`z`$-component of each spin is now substantially different from zero. On the other hand, the Holstein-Primakoff transformation (HPT) HolsteinP40

$`\sqrt{2}\widehat{S}^+=\sqrt{S+\stackrel{~}{S}\widehat{z}^2}(\widehat{q}+i\widehat{p}),`$ (4)
$`\widehat{S}^{}=(\widehat{S}^+)^{},\widehat{S}^z=\stackrel{~}{S}\widehat{z}^2,`$
and the Dyson-Maleev one (DMT) DysonM56

$`\sqrt{2}\widehat{S}^+=\widehat{q}+i\widehat{p},\widehat{S}^{}=(\widehat{q}i\widehat{p})(S+\stackrel{~}{S}\widehat{z}^2),`$ (5)
$`\widehat{S}^z=\stackrel{~}{S}\widehat{z}^2,`$
with $`\widehat{z}^2(\widehat{q}^2+\widehat{p}^2)/2`$, do both suggest the $`z`$-component to be the privileged one for alignment, thus fitting to the $`|\mu |<1`$ case.

The isotropic, or nearly isotropic, case is the most difficult to be treated, as no part of the spherical phase-space may be generically chosen to be described better than another; nevertheless, when the ground state is at least characterized by long-range order with an alignment axis, the HP and DM transformations are both seen to work well in the PQSCHA scheme. The reason is that the boson picture only serves to derive the pure-quantum renormalizations, while the symmetry is thereafter restored in $`_{\mathrm{eff}}`$ so that it is sufficient to assume a local alignment axis.

## 3 The easy-plane case

The Hamiltonian Eq. (1) in the easy-plane case takes the form

$$\widehat{}=J\underset{<\mathrm{𝐢𝐣}>}{}\left[\left(\widehat{S}_𝐢^x\widehat{S}_𝐣^x+\widehat{S}_𝐢^y\widehat{S}_𝐣^y\right)+\lambda \widehat{S}_𝐢^z\widehat{S}_𝐣^z\right]$$
(6)
with $`\lambda (1,1)`$. The antiferromagnetic sector is mapped in the $`\lambda (1,0]`$ region of Eq. (6) by the canonical transformation $`(\widehat{S}_𝐢^x,\widehat{S}_𝐢^y,\widehat{S}_𝐢^z)((1)^𝐢\widehat{S}_𝐢^x,(1)^𝐢\widehat{S}_𝐢^y,\widehat{S}_𝐢^z)`$ where $`(1)^𝐢(1)^{i_1+i_2}`$; ferro- and antiferromagnets may be thus simultaneously studied.

The effective Hamiltonian relative to Eq. (6) is

$$_{\mathrm{eff}}=J\stackrel{~}{S}^2j_{\mathrm{eff}}\underset{<\mathrm{𝐢𝐣}>}{}\left[\left(s_𝐢^xs_𝐣^x+s_𝐢^ys_𝐣^y\right)+\lambda _{\mathrm{eff}}s_𝐢^zs_𝐣^z\right]+𝒢,$$
(7)
where the renormalization parameters $`j_{\mathrm{eff}}(t,\lambda ,S)`$,$`\lambda _{\mathrm{eff}}(t,\lambda ,S)`$, and $`𝒢(t,\lambda ,S)`$ have different expressions depending on the $`\lambda `$-region considered.

In the $`\lambda 1`$ case, the VT Eqs. (3) may be safely used, and give CTVVprb95

$`j_{\mathrm{eff}}^\mathrm{V}`$ $`=`$ $`(1{\displaystyle \frac{1}{2}}D_{})^2e^{𝒟_{}/2},`$ (8)
$`\lambda _{\mathrm{eff}}^\mathrm{V}`$ $`=`$ $`\lambda (1{\displaystyle \frac{1}{2}}D_{})^1e^{𝒟_{}/2},`$ (9)
$`𝒢^\mathrm{V}`$ $`=`$ $`J\stackrel{~}{S}^2N\left[t\mathrm{\Gamma }{\displaystyle \frac{t}{2}}\mathrm{ln}\left(1{\displaystyle \frac{1}{2}}D_{}\right)\mathrm{\Theta }^\mathrm{V}\right],`$ (10)
where the renormalization coefficients $`D_{}`$ and $`𝒟_{}`$ represent the effects of in-plane and out-of-plane pure-quantum fluctuations, respectively, and have the form

$`D_{}`$ $`=`$ $`{\displaystyle \frac{1}{2\stackrel{~}{S}N}}{\displaystyle \underset{𝐤}{}}{\displaystyle \frac{b_𝐤}{a_𝐤}}_𝐤,`$ (11)
$`𝒟_{}`$ $`=`$ $`{\displaystyle \frac{1}{2\stackrel{~}{S}N}}{\displaystyle \underset{𝐤}{}}(1\gamma _𝐤){\displaystyle \frac{a_𝐤}{b_𝐤}}_𝐤,`$ (12)
with

$`a_𝐤^2`$ $`=`$ $`4e^{𝒟_{}/2}(1\lambda _{\mathrm{eff}}\gamma _𝐤),`$ (13)
$`b_𝐤^2`$ $`=`$ $`4(1{\displaystyle \frac{1}{2}}D_{})^2e^{𝒟_{}/2}(1\gamma _𝐤),`$ (14)
$`_𝐤=(\mathrm{coth}f_𝐤1/f_𝐤)`$, $`\mathrm{\Gamma }=N^1_𝐤\mathrm{ln}(\mathrm{sinh}f_𝐤/f_𝐤)`$, $`f_𝐤=a_𝐤b_𝐤/(2\stackrel{~}{S}t)`$, $`\gamma _𝐤=_𝐝\mathrm{cos}(𝐤𝐝)/4`$, $`𝐝=(\pm 1,\pm 1)`$, and $`𝐤`$ is a wave vector in the first Brillouin zone. The uniform coefficient $`\mathrm{\Theta }^\mathrm{V}`$ is

$$\mathrm{\Theta }^\mathrm{V}=e^{𝒟_{}/2}\left(2D_{}+(1D_{})𝒟_{}\right).$$

Close to the isotropic limit, $`\lambda 1`$, the HPT must be used: because of the residual easy-plane character of the model, the privileged axis, i.e. the quantization one, must be chosen in the easy plane; in particular, we choose the $`y`$ direction as the local alignment one. A quite complicated PQSCHA implementation finally leads to the following expressions CCTVV98 :

$`j_{\mathrm{eff}}^{\mathrm{HP}}`$ $`=`$ $`\theta ^4,`$ (15)
$`\lambda _{\mathrm{eff}}^{\mathrm{HP}}`$ $`=`$ $`\lambda +{\displaystyle \frac{d}{\theta ^2}}(1\lambda )+{\displaystyle \frac{D^{pp}}{\theta ^2}}(1\lambda )^2,`$ (16)
$`𝒢^{\mathrm{HP}}`$ $`=`$ $`J\stackrel{~}{S}^2N\left[t\mathrm{\Gamma }+{\displaystyle \frac{\theta ^2}{N\stackrel{~}{S}}}{\displaystyle \underset{𝐤}{}}a_𝐤b_𝐤_𝐤\mathrm{\Theta }^{\mathrm{HP}}\right],`$ (17)
where the temperature and spin dependent renormalization coefficients are defined as follows:

$`\theta ^2=1{\displaystyle \frac{1}{2}}𝒟+{\displaystyle \frac{1}{2}}d,d={\displaystyle \frac{1}{2}}(D^{qq}\lambda _{\mathrm{eff}}D^{pp}),`$ (18)
$`𝒟={\displaystyle \frac{1}{N\stackrel{~}{S}}}{\displaystyle \underset{𝐤}{}}(1\gamma _𝐤){\displaystyle \frac{a_𝐤}{b_\mathrm{k}}}_𝐤,`$ (19)
and

$$D^{pp}=\frac{1}{2\stackrel{~}{S}N}\underset{𝐤}{}\frac{a_𝐤}{b_\mathrm{k}}\gamma _𝐤_𝐤,D^{qq}=\frac{1}{2\stackrel{~}{S}N}\underset{𝐤}{}\frac{b_𝐤}{a_\mathrm{k}}\gamma _𝐤_𝐤,$$

with dimensionless frequencies

$`a_𝐤^2`$ $`=`$ $`4\theta ^2(1\lambda _{\mathrm{eff}}\gamma _𝐤),`$ (20)
$`b_𝐤^2`$ $`=`$ $`4\theta ^2(1\gamma _𝐤).`$ (21)
The uniform coefficient $`\mathrm{\Theta }^{\mathrm{HP}}`$ is

$`\mathrm{\Theta }^{\mathrm{HP}}`$ $`=`$ $`D^{qq}(13D^qD^p)+\lambda D^{pp}(33D^pD^q)+`$
$`+`$ $`2(D^{qq})^2+2(D^{pp})^2(D^q+D^p)^2+2(D^q+D^p),`$
with

$$D^p=\frac{1}{2\stackrel{~}{S}N}\underset{𝐤}{}\frac{a_𝐤}{b_\mathrm{k}}_𝐤,D^q=\frac{1}{2\stackrel{~}{S}N}\underset{𝐤}{}\frac{b_𝐤}{a_\mathrm{k}}_𝐤.$$

The renormalization of the exchange energy by the factor $`j_{\mathrm{eff}}<1`$, and the weakening of the easy-plane anisotropy ($`|\lambda ||\lambda _{\mathrm{eff}}|`$), are seen to be, both for strong and weak anisotropy, the result of the cooperative effect of in-plane and out-of plane pure-quantum fluctuations. It is worthwhile noticing that, in the isotropic limit $`|\lambda |=1`$, the effective Hamiltonian (7), determined by the HPT, coincides with the one found directly for the isotropic model by the DMT.

In Fig. 1 we show the renormalization parameters $`j_{\mathrm{eff}}`$ vs. $`t`$, for different values of $`S`$ and $`\lambda `$; the two most (least) anisotropic cases are treated by the VT (HPT). For $`S=1`$ and $`\lambda =0.5`$, $`j_{\mathrm{eff}}`$ as obtained by the HPT is also shown (dotted line): the difference with the VT result (dashed line) is remarkable, testifying that both transformations cannot give very accurate results in such intermediate region. However, as we will see in Section 5, this does not dramatically affect the critical temperature estimation.

The difference $`(\lambda _{\mathrm{eff}}\lambda )`$ is shown in Fig. 2 as a function of $`\lambda `$, for different values of $`S`$ and $`t`$. For each couple $`(t,S)`$ the curves passing through the origin are obtained by the VT, while those passing through the point $`(1,0)`$ or $`(1,0)`$ are obtained by the HPT in the antiferro- or ferromagnetic case, respectively; the two types of results do not smoothly connect to each other, but nevertheless cover the whole $`[1,1]`$ interval and show a behaviour of the same type of that found in the easy-axis case (see Fig.5), where the problem of using two different spin boson transformations is not present. As expected, the HP curves display the correct $`|\lambda |1`$ behaviour (i.e. $`|\lambda _{\mathrm{eff}}|^{\mathrm{HP}}1`$), while $`\lambda _{\mathrm{eff}}^\mathrm{V}`$ is seen to be proportional to $`\lambda `$, when $`\lambda 0`$.

As mentioned in the Introduction, the easy-plane models are characterized by a critical phase, with vanishing magnetization and diverging correlation length, extending in the temperature region $`0<t<t_{\mathrm{BKT}}`$; thermodynamic quantities that may be significantly studied in such phase are, for instance, the free energy and the specific heat. To this respect, notice that the uniform term $`𝒢`$, Eqs. (10) and (17), not entering the statistical averages’ calculation, is essential in the evaluation of the partition function $`𝒵`$.

In the paramagnetic phase $`t>t_{\mathrm{BKT}}`$, one of the fundamental thermodynamic quantities to be investigated, is the in-plane correlation length defined by the asymptotic behaviour of the correlation functions

$$G(r)\frac{\eta _𝐫}{\stackrel{~}{S}^2}\widehat{S}_𝐢^x\widehat{S}_{𝐢+𝐫}^x+\widehat{S}_𝐢^y\widehat{S}_{𝐢+𝐫}^y\underset{r\mathrm{}}{}e^{\frac{r}{\xi }}$$
(22)
with $`𝐫=(r_1,r_2)`$ any vector on the square lattice, $`r|𝐫|`$ and $`\eta _𝐫=1`$ or $`(1)^{r_1+r_2}`$ in the ferro- or antiferromagnetic case.

By using Eq. (2) the following PQSCHA expression is found

$$G(r)=\mathrm{\Delta }_𝐫s_𝐢^xs_{𝐢+𝐫}^x+s_𝐢^ys_{𝐢+𝐫}^y_{\mathrm{eff}},$$
(23)
where $`_{\mathrm{eff}}𝒵^1d^N𝐬()e^{\beta _{\mathrm{eff}}}`$ is the classical-like statistical average defined by the effective Hamiltonian.

When the VT is used, i.e. in the strongly easy-plane case, Eq. (23) holds for all values of $`r`$, with

$$\mathrm{\Delta }_𝐫^{\mathrm{VT}}=(1\frac{1}{2}𝒟_{})^2e^{𝒟_{}/2}e^{D_𝐫},$$
(24)
and

$$D_𝐫=\frac{1}{\stackrel{~}{S}N}\underset{𝐤}{}\frac{a_𝐤}{b_𝐤}\mathrm{cos}(𝐤𝐫)_𝐤.$$

In the nearly isotropic region, the use of the HPT leads to a much more complicated general expression for $`G(r)`$, that nonetheless goes to expression (23) with coefficient

$$\mathrm{\Delta }_𝐫^{\mathrm{HP}}\left(1\frac{1}{2}(D^q+D^p)\right)\left(1\frac{1}{8}(5D^q+3D^p)\right),$$
(25)
for large $`r`$ . From Eqs. (24) and (25), the renormalization coefficient $`\mathrm{\Delta }_𝐫`$ is seen to converge to a finite value when $`r\mathrm{}`$; this property, as we will see in Section 5, is of fundamental importance when the critical behaviour of the model is under investigation. In particular it means that the correlation length of the quantum model is related with that of its classical counterpart by the relation

$$\xi (t,\lambda ,S)=\xi ^{\mathrm{cl}}(t_{\mathrm{eff}},\lambda _{\mathrm{eff}})$$
(26)
with $`t_{\mathrm{eff}}t/j_{\mathrm{eff}}`$. This relation allows us to evaluate the correlation length of a quantum model with spin $`S`$, at a given temperature $`t`$, by performing a classical MC simulation on a model with anisotropy $`\lambda _{\mathrm{eff}}`$, at the effective temperature $`t_{\mathrm{eff}}`$; a particularly simple case is that of the $`XY`$ model $`\lambda =\lambda _{\mathrm{eff}}=0`$, whose correlation length may be directly determined in terms of the classical one, by a simple temperature scaling. Fig. 3 shows the correlation length versus $`t`$, for $`S=1`$ and $`\lambda =0`$, $`0.5`$, $`0.999`$, and $`1`$. The classical MC data for $`\lambda =0`$ and $`\lambda =0.999`$, Refs. CTV95  and CCTVV98  respectively, are also shown.

## 4 The easy-axis case

The Hamiltonian Eq. (1) in the easy-axis case takes the form

$$\widehat{}=J\underset{<\mathrm{𝐢𝐣}>}{}\left[\mu \left(\lambda \widehat{S}_𝐢^x\widehat{S}_𝐣^x+\widehat{S}_𝐢^y\widehat{S}_𝐣^y\right)+\widehat{S}_𝐢^z\widehat{S}_𝐣^z\right]$$
(27)
with $`\mu (1,1)`$ and $`\lambda =\mathrm{sign}(\mu )`$. The antiferromagnetic sector is mapped in the $`\mu (1,0]`$ region of Eq. (27) by the canonical transformation $`(\widehat{S}_𝐢^x,\widehat{S}_𝐢^y,\widehat{S}_𝐢^z)((1)^𝐢\widehat{S}_𝐢^x,\widehat{S}_𝐢^y,(1)^𝐢\widehat{S}_𝐢^z)`$. Because of the easy-axis character of the model, the HP and DM transformations may be safely used, and actually give the same results; the latter, however, may be preferred because of its simpler structure.

The PQSCHA effective Hamiltonian relative to Eq.(27) is found to be CRTVV00

$$_{\mathrm{eff}}=J\stackrel{~}{S}^2j_{\mathrm{eff}}\underset{<\mathrm{𝐢𝐣}>}{}\left[\mu _{\mathrm{eff}}\left(\lambda s_𝐢^xs_𝐣^x+s_𝐢^ys_𝐣^y\right)+s_𝐢^zs_𝐣^z\right]+𝒢,$$
(28)
where $`j_{\mathrm{eff}}(t,\mu ,S)`$, $`\mu _{\mathrm{eff}}(t,\mu ,S)`$, and $`𝒢(t,\mu ,S)`$ are

$`j_{\mathrm{eff}}=\theta _{}^4,\mu _{\mathrm{eff}}=\mu {\displaystyle \frac{\theta _{}^2}{\theta _{}^2}},`$ (29)
$`𝒢=2J\stackrel{~}{S}^2(1\theta _{}^4)+J\stackrel{~}{S}^2\mathrm{\Gamma },`$ (30)
with

$`\theta _{}^2=1{\displaystyle \frac{𝒟_{}}{2}},\theta _{}^2=1{\displaystyle \frac{𝒟_{}}{2}},`$ (31)
$`\mathrm{\Gamma }=t{\displaystyle \underset{𝐤}{}}\mathrm{ln}\left({\displaystyle \frac{\mathrm{sinh}f_𝐤}{\theta _{}^2f_𝐤}}\right),`$ (32)
and the coefficients

$`𝒟_{}`$ $`=`$ $`{\displaystyle \frac{1}{N\stackrel{~}{S}}}{\displaystyle \underset{𝐤}{}}{\displaystyle \frac{a_𝐤}{b_𝐤}}\left(1\mu \lambda \gamma _𝐤\right)_𝐤,`$
$`𝒟_{}`$ $`=`$ $`{\displaystyle \frac{1}{N\stackrel{~}{S}}}{\displaystyle \underset{𝐤}{}}{\displaystyle \frac{a_𝐤}{b_𝐤}}\left(1{\displaystyle \frac{\gamma _𝐤}{\mu \lambda }}\right)_𝐤`$ (33)
are self-consistently determined by solving Eqs. (31) and (33), with dimensionless frequencies

$`a_𝐤^2`$ $`=`$ $`4\left(\theta _{}^2\mu \theta _{}^2\gamma _𝐤\right),`$ (34)
$`b_𝐤^2`$ $`=`$ $`4\left(\theta _{}^2\mu \lambda \theta _{}^2\gamma _𝐤\right).`$ (35)
As in the easy-plane case, quantum renormalizations weaken both the energy scale ($`j_{\mathrm{eff}}<1`$) and the anisotropy ($`|\mu _{\mathrm{eff}}|>\mu `$). In Fig. 4 we show the renormalization parameter $`j_{\mathrm{eff}}`$ vs. $`t`$ for different values of $`S`$ and $`\mu `$. In Fig. 5, where the difference $`\mu _{\mathrm{eff}}\mu `$ is shown as a function of $`\mu `$, we see that, at variance with the easy-plane case (see Fig. 2), the almost isotropic regime is smoothly connected with the strongly axial one, testifying to the suitableness of the DMT in treating the whole easy-axis subclass of models.

When $`\mu `$ vanishes the renormalization coefficient $`𝒟_{}`$ may be shown to keep finite, so that $`\mu _{\mathrm{eff}}0`$, and the $`Z`$ model, with a single optical mode $`a_𝐤^2=b_𝐤^2=4\theta _{}^2`$, $`𝐤`$, is recovered; for $`S=1/2`$ such model coincides with the Ising one.

The easy-axis case is characterized by a finite temperature phase-transition towards a fully ordered phase; many thermodynamic properties may be hence studied both above and below the critical temperature $`t_\mathrm{I}`$, and, in particular, the PQSCHA expression for the magnetization along the easy axis $`m_𝐢\eta _𝐢\widehat{S}_𝐢^z/N\stackrel{~}{S}`$ is

$$m=\theta _{}^2s_𝐢^z_{\mathrm{𝐞𝐟𝐟}}.$$
(36)
The most significant quantity in the paramagnetic phase $`t>t_\mathrm{I}`$ is the correlation length, here defined by the asymptotic behaviour of the isotropic correlation functions

$$G(r)\frac{\eta _𝐫}{\stackrel{~}{S}^2}\widehat{𝐒}_𝐢\widehat{𝐒}_{𝐢+𝐫}\underset{r\mathrm{}}{}e^{\frac{r}{\xi }};$$
(37)
the PQSCHA expression for $`G(r)`$ is

$$G(r)=\theta _𝐫^4𝐬_𝐢𝐬_{𝐢+𝐫}_{\mathrm{eff}},$$
(38)
where $`\theta _𝐫^2=1𝒟_𝐫/2`$ and

$$𝒟_𝐫=\frac{1}{N\stackrel{~}{S}}\underset{𝐤}{}\frac{a_𝐤}{b_𝐤}\left(1\mathrm{cos}(𝐤𝐫)\right)_𝐤$$

is a further site-dependent renormalization coefficient. For increasing $`r`$, as in the easy-plane case, the coefficient $`\theta _𝐫^4`$ keeps finite and rapidly converges to a uniform term: the asymptotic behaviour of $`G(r)`$ is hence determined by that of the classical-like correlation functions $`𝐬_𝐢𝐬_{𝐢+𝐫}_{\mathrm{eff}}`$, and the relation

$$\xi (t,\mu ,S)=\xi ^{\mathrm{cl}}(t_{\mathrm{eff}},\mu _{\mathrm{eff}})$$
(39)
may be used. As in the easy-plane case, results for the quantum reference ($`Z`$) model are obtained by a simple temperature scaling of the classical data; we have hence performed MC simulations on the classical $`Z`$ model, and produced results for the quantum model with $`S=1/2`$, $`1`$ and $`5/2`$. The corresponding magnetization and correlation-length curves are shown in Figs.6 and 7, respectively. As for the latter, notice the much sharper divergence with respect to the $`XY`$ model (compare the dashed curve in Fig.7 with the full curve of Fig.3).

## 5 Transition temperatures

The PQSCHA expressions for the effective Hamiltonian and the correlation functions contain two essential pieces of information: (a) the effective Hamiltonian keeps the symmetry properties of the original quantum model; (b) the quantum correlation functions share the asymptotic behaviour with their classical counterpart. These two statements not only lead us to the relations (26) and (39), but also allow us to assert that the critical behaviour of the quantum model is that of its effective classical counterpart, and that, for the critical temperature, the relation

$$t_c(\nu ,S)=j_{\mathrm{eff}}(t_c,\nu ,S)t_c^{\mathrm{cl}}(\nu _{\mathrm{eff}}(t_c,\nu ,S))$$
(40)
holds.

Due to the temperature dependence of $`j_{\mathrm{eff}}`$ and $`\nu _{\mathrm{eff}}`$, Eq. (40) is quite involute; it may be nonetheless numerically solved if an analytical expression for $`t_c^{\mathrm{cl}}(\nu )`$ is available. Such expression does not actually exist, neither in the easy-plane nor in the easy-axis case; we have hence collected a set of classical MC data properly distributed in the $`[0,1)`$ interval, in order to determine a precise interpolating function $`\tau _c^{\mathrm{cl}}(\nu )`$.

In the easy-plane case, classical MC data have been taken from Ref. CTV95  and interpolated by the function

$`\tau _{\mathrm{BKT}}^{\mathrm{cl}}(\lambda )=a\left(1+b\lambda ^2+c\lambda ^4d\mathrm{ln}(1\lambda ^2)\right)^1,`$
$`a=0.695,b=0.012,c=0.032,d=0.0648,`$
where the $`\lambda \lambda `$ invariance has been imposed.

In the easy-axis case, sources of the classical MC data have been Refs. SerenaGL93  and GouveaEtal99 , as well as our new data $`t_\mathrm{I}^{\mathrm{cl}}(0.5)=0.88\pm 0.01`$ and $`t_\mathrm{I}^{\mathrm{cl}}(0.8)=0.81\pm 0.01`$; the resulting interpolating function is

$`\tau _\mathrm{I}^{\mathrm{cl}}(\mu )=a\left(1+b\mu ^2+c\mu ^4d\mathrm{ln}(1\mu ^2)\right)^1,`$
$`a=0.917,b=0.068,c=0.097,d=0.0636,`$
where, again, the constraint $`t_\mathrm{I}^{\mathrm{cl}}(\mu )=t_\mathrm{I}^{\mathrm{cl}}(\mu )`$ has been imposed.

Equations (5) and (5) should only be considered as reasonable interpolating functions of the available data; in particular, they do not reproduce the correct asymptotic behaviour in the $`\nu 1`$ isotropic limit. Such asymptotic behaviours, on the other hand, are not accessible by numerical techniques and are actually determined by Renormalization-Group approaches. However, all of the numerical and experimental data are in the $`\nu `$-region where $`t_c(\nu )`$ is sensibly different from zero, as seen in Figs. 8 and 9, i.e. where the above mentioned asymptotic behaviours have not set in yet.

Once $`t_c^{\mathrm{cl}}(\nu )\tau _c^{\mathrm{cl}}(\nu )`$ has been determined, Eq. (40) may be numerically solved thus giving the value of the quantum critical temperature, for any value of $`\nu `$ and $`S`$, in a few seconds on a standard PC.

In Fig. 8 we show the resulting curves for $`S=1/2`$, $`1`$, $`5/2`$, and $`\mathrm{}`$ in the easy-plane case: for each spin, the whole $`(1,1)`$ interval is covered by two different types of curves, corresponding to the use of $`j_{\mathrm{eff}}^\mathrm{V}`$,$`\lambda _{\mathrm{eff}}^\mathrm{V}`$ and $`j_{\mathrm{eff}}^{\mathrm{HP}}`$,$`\lambda _{\mathrm{eff}}^{\mathrm{HP}}`$ in the strongly easy-plane and nearly isotropic regions, respectively. The available quantum MC data DingM90 ; Ding92  are also shown, and agree very well with our results, despite being in the region where, because of the strong quantum fluctuations, the use of the PQSCHA becomes more delicate; unfortunately no experimental data exist, to our knowledge, for $`t_{\mathrm{BKT}}`$.

In Fig. 9 the transition temperature $`t_\mathrm{I}(\mu ,S)`$ is shown for $`S=1/2`$, $`1`$, $`5/2`$, and $`\mathrm{}`$; in this case, there exist several experimental data, for the real compounds K<sub>2</sub>NiF<sub>4</sub> ($`\mu =0.996`$, $`S=1`$, $`t_\mathrm{I}^{\mathrm{exp}}=0.416`$) deWijnWW73 ; SkalyoEtal69 , Rb<sub>2</sub>NiF<sub>4</sub> ($`\mu =0.982`$, $`S=1`$, $`t_\mathrm{I}^{\mathrm{exp}}=0.477`$) NagataT74 , K<sub>2</sub>MnF<sub>4</sub> ($`\mu =0.995`$, $`S=5/2`$, $`t_\mathrm{I}^{\mathrm{exp}}=0.553`$) deWijnWW73 ; BirgeneauGS73 , Rb<sub>2</sub>MnCl<sub>4</sub> ($`\mu =0.997`$, $`S=5/2`$, $`t_\mathrm{I}^{\mathrm{exp}}=0.558`$) SchroederEtal80 , and Rb<sub>2</sub>MnF<sub>4</sub> ($`\mu =0.994`$, $`S=5/2`$, $`t_\mathrm{I}^{\mathrm{exp}}=0.575`$) deWijnWW73 ; CowleyEtal77 , whose agreement with our results is very good, despite being in the most difficult region to be studied, i.e. in the nearly isotropic one.

The $`S=1/2`$ easy-axis antiferromagnetic case deserves a few more comments, as a quite well distributed scan of the $`\mu [1,0)`$ region may be performed by putting together the exact result for the Ising model Onsager44 , $`t_\mathrm{I}(0,1/2)=0.567`$, the quantum MC data by Ding Ding90 , $`t_\mathrm{I}(0.5,1/2)=0.5`$, $`t_\mathrm{I}(0.99,1/2)=0.298`$, and the experimental data for the real compound YBa<sub>2</sub>Cu<sub>3</sub>O<sub>6.1</sub> ($`\mu 0.992`$, $`S=1/2`$, $`t_\mathrm{I}^{\mathrm{exp}}=0.310`$) RossatMignodEtal91 . As for the PQSCHA, we know that its results are quantitatively reliable if quantum renormalizations are not too strong: a reasonable criterion to check whether such condition is fullfilled or not is to require $`j_{\mathrm{eff}}0.5`$, meaning a quantum renormalizations of the energy scale of about $`50\%`$. Such criterion, as seen in Fig. 4, is not satisfied for $`S=1/2`$ and $`t0.5`$: our $`t_\mathrm{I}(\mu ,1/2)`$ curve does in fact underestimate the most anisotropic numerical and experimental data, despite displaying the correct qualitative behaviour. A significant improvement may be obtained by using the PQSCHA with the modified Low Coupling Approximation, as defined in Ref. CTVV97 , whose results are shown by the dashed line. This modified version of the method has the disadvantage, however, of not being capable to cover the whole $`(1,1)`$ $`\mu `$-interval, because of the loss of solution of its self-consistent equations when moving towards the isotropic limit (reason for the dashed curve in Fig. 9 to be interrupted).

On the other hand, the almost isotropic region, which is the most interesting from the experimental point of view, is well described by our results, even for $`S=1/2`$, as seen in Fig. 10.

## 6 Conclusions

The results found by the PQSCHA for the 2d Heisenberg antiferromagnets with easy-plane or easy-axis anisotropy, show that quantum fluctuations introduce temperature, anisotropy, and spin dependent renormalizations of both the energy scale and the anisotropy of the model, consequently reducing the temperature at which a phase transition, of the BKT or Ising type, is expected. Such reduction, however, is never seen to push the critical temperature down to zero, so that the whole class of quantum models described by Eq. (1) with $`|\mu ||\lambda |`$ turns out to be characterized by a finite temperature transition.

In Fig.11 a global picture of the situation is visualized by the $`t_c`$ curves for different spin values, versus the ratio $`\lambda /\mu `$: the central region corresponds to the easy-plane case, while the two external branches represents the easy-axis ferro- and antiferromagnetic cases. The $`t_c`$ reduction is seen to be more marked for small spin and in the ferromagnetic case, thus leading to the conclusion that, should $`t_c`$ vanish for some critical $`\nu _c(S)`$, we expect $`|\nu _c(S)|`$ to be an increasing function of $`S`$ which is larger in the antiferromagnetic case, and such that its difference from unity is less than $`10^2`$. In the $`S=1/2`$ case, despite being the one for which the PQSCHA is less precise, our picture completely agrees with that proposed by Ding in Ref. Ding90  on the basis of quantum MC data. In the antiferromagnetic $`S=1/2`$ easy-axis case, on the other hand, Branco and De Sousa BrancodeS00  predict, from a real space renormalization group analysis, the existence of a critical $`\mu _c(1/2)0.8`$ at which $`t_\mathrm{I}`$ should vanish, and detect a reentrance in the $`\mu `$ dependence of such temperature; they found no such anomaly in the ferromagnetic sector. This scenario is in contrast not only with ours and Ding’s results, but also with experimental data.

Finally, from the experimental point of view, our results show that anisotropies, even if as small as those measured in most real compounds, are fundamental ingredients in determining the low-temperature behaviour of the materials; it is hence essential, in order to perform a meaningful analysis of the experimental data, to have at least an estimate of the temperature at which a possible BKT or Ising-like phase transition should occur. Our approach allows a determination of such temperature for any given value of $`S`$ and $`\nu `$, therefore representing an important tool in the experimental investigation of two-dimensional Heisenberg magnets.

## 7 Acknowledgements

The authors wish to thank Dr. Luca Capriotti for his contribution in the early stage of the work. This research has been partially supported by the COFIN98-MURST fund.


text:
# Generation of and Debugging with Logical Pre and Postconditions11footnote 1In M. Ducassé (ed), proceedings of the Fourth International Workshop on Automated Debugging (AADEBUG 2000), August 2000, Munich. COmputer Research Repository (http://www.acm.org/corr/), cs.SE/0101009; whole proceedings: cs.SE/0010035.

## 1 Introduction

The paper presents the debugging subsystem of the ongoing project SLAM. The SLAM system allows the user to specify a program in a very high level specification language. It is an object oriented formal specification language that integrates *algebraic specifications* and *model-based specifications*. An algebraic specification, like those proposed by the OBJ language family  or Larch-LSL , is self-contained and independent of the chosen types in the code. Basically a system is described by a decomposition in data types/classes. The behaviour of an operation is described in terms of other operations. On the other hand, specification languages based on abstract models, as Z , VDM  or Larch interfaces languages , have a series of primitive mathematical domains (sets, sequences, tables, etc) to model in an abstract way all data identified during the process of development. Specification of operations uses (explicitly or implicitly) two predicates (pre/postconditions) that describe the relationship between the input and the output by means of a logic formula.

As we will see, SLAM unifies both kind of languages by specifying operations by logical pre and postconditions, but restricting logical formulae to a computable view of quantifiers as traversal operations on data.

The language is the heart of a system that integrates all the stages in the programming process: analysis, design, implementation, documentation and validation.

A SLAM program is not directly stored in a text file. The development environment allows to declare the full specification in a convenient way. Different SLAM components are different views of the system and they can be edited independently. In order to facilitate the understanding of SLAM we will show SLAM elements with a syntax that does not necessarily correspond neither with an internal representation nor the system presentation. They are generated via a friendly interactive interface, so the reader should not pay too much attention to the concrete syntax presented in this paper.

The SLAM system is able to generate executable and readable code in a high level object oriented language. Furthermore, the code contains runtime checkable assertions (i.e. the pre and postconditions of operations) that will help in the declarative debugging process of the program. The user can change the automatically generated code (for instance, to make it more efficient) but the assertions can be reused to ensure that the new code behaves correctly.

The assertions are complex logical formulae, so they are, in principle, difficult to check. The SLAM system generates a Prolog program to check them. The Prolog program is linked with the C++ program to achieve the desired effect.

A similar goal is present in some related works: Anna  is an Ada extension that includes facilities for formally specifying the intended behaviour of Ada programs, and the runtime checking of them. The assertions are limited to Ada constructions and they work mainly with algebraic specifications. In  a framework for assertion-based debugging is presented: assertions are written using Prolog and a type language so the user cannot specify properties in such an abstract way as in SLAM. Other related works are the result checking approach  (the user must specify a new algorithm in order to check the result of the original one), and relative debugging  (where it is possible to compare the execution of two programs with the same functionality) Disadvantages appear clear, both algorithms/programs might be wrong and some error might be undetectable.

¿From the debugging point of view, the most novel feature of our proposal is that the specification language SLAM is designed as a trade-off between a high expressiveness and the possibility of compilation. It serves both for specifying many useful properties about programs and, at the same time, to generate executable and readable prototypes. It is possible because of the computable behaviour of quantifiers thanks to the object oriented structure of the language.

We present here just a small subset of SLAM features. The discussion of full SLAM is beyond the aims of the paper and can be found in the SLAM webpage . We focus on the most significant SLAM features and how to obtain the Prolog code to check the assertions. The translation from SLAM to Prolog is fully formalized.

The paper organization is the following: we present the language in section 2, compilation schemes into C++ and Prolog in section 3 and the way in which Prolog assertion code is linked with the C++ program are presented in section 4. Section 5 presents conclusions and future work.

## 2 The Specification Language

SLAM is an object oriented specification language. In this paper we present a functional (i.e. stateless) version of the language. A SLAM program consists in a collection of user defined and predefined classes. A SLAM execution is an expression involving one or more SLAM objects and function (method) calls. The next sections describe the main SLAM components.

### 2.1 Classes

In SLAM a class is defined by specifying its properties. These properties declare and define all the characteristics of the class. A class is merely declared by giving a class name.

A class can declare *internal attributes*. Attributes specify the internal representation of instances of the class. In SLAM attributes are not defined explicitly as in most of the imperative object oriented languages. A more declarative construction (*algebraic types*) has been directly introduced into SLAM to indicate that a certain syntactical construction belongs to the class.

Every scheme of declaration of attributes defines an internal hidden *attribute constructor*. The attribute constructor and its arguments define an *internal representation* of the object and specification of operations can be written based on that model. For example, if we need a class to model 2D points, we can define the following class:

| class Point is |
| --- |
| Cartesian (Real,Real) $``$ Point |

and now expressions like Cartesian (1,2.5) are instances of the class Point.

There is no restriction on the names of these attribute constructors, it can even be omitted and replaced by a label222This label, expressed as label &, can be omitted when there is just one alternative.. For example, next examples show the use of *aggregation* in order to define the classes of segments and stacks:

| class Segment is |
| --- |
| seg & {source : Point, destination : Point} $``$ Segment |

| class Stack (Elem) is |
| --- |
| contents & {top : Nat, elements : Seq (Elem)} $``$ Stack |

The last example shows how classes can be parameterized. SLAM provides bounded parametric polymorphism in the same style of Pizza . Some predefined SLAM constructions have been used:

* Record type construct with its standard semantics, for instance to define components indicating a source and a destination point.
* Sequences, that are indexed collections of elements. In the Stack class it is used to store the different elements in the stack.

In contrast with other object oriented languages alternative representations are allowed. In SLAM a class can have several alternative sets of attributes, the style is similar to how to define new types in a functional language and quite related to *union types* or *variant records* in some imperative languages. A very similar construct can be found in Pizza .

The point example can be extended to represent points in Polar coordinates maintaining the Cartesian representation as another alternative:

| class Point is |
| --- |
| Cartesian (Real,Real) $``$ Point |
| Polar (Real,Real) $``$ Point |

Now, the expression Polar (4.5,1.57) also represents an object that belong to the class Point.

The use of alternatives extends to the definition of recursive data structures. Let see a typical example of a recursive data structure in SLAM:

| class Tree (Elem) is |
| --- |
| Empty $``$ Tree |
| Node (Tree (Elem), Elem, Tree (Elem)) $``$ Tree |

Up to now, there is no possibility to have references to object, so it is not possible to include side effects. We plan to extend the language in this vein.

### 2.2 Class relationships

#### 2.2.1 Inheritance

SLAM classes can be defined from the scratch by means of (multiple) *inheritance* from other class. In contrast with some other object oriented languages attribute definitions can be refined by the subclass by using the two usual kinds of inheritance:

* Extension: New components are added to an attribute constructor.
class ColouredPoint is   ColouredPoint isa Point   Cartesian (Real,Real, Colour) $``$ ColouredPoint
* Overriding (or refinement): The number of components/arguments in an attribute constructor remains the same but some of the components are replaced by subclasses of the original classes.
class ColouredSegment is   ColouredSegment isa Segment   seg & {source : ColouredPoint, destination : ColouredPoint} $``$ ColouredSegment

#### 2.2.2 Aggregation

Any class can be specified by declaring a representation based on attributes that are instances of other classes. In the object oriented model the structural relationship between classes is called *aggregation* or *composition*.

#### 2.2.3 Association

*Abstract classes* understood as *Interfaces* are an important component of SLAM: they can be used to define an abstract behaviour and other classes can indicate that they share this behaviour. The main difference is that this “indication” can be done by two alternative mechanisms. One is *inheritance* and the user need to supply the missing code or to reuse it. The other one is imitation. A class The\_Class can *imitate* (implement in Java terminology) the behaviour of another abstract class Abstract\_Class by matching all its components (attributes if any, functions) by components of The\_Class.

Abstract classes and imitation provides the full power of theories (in OBJ terminology) as well as type classes (à la Haskell ) playing a more powerful role than C++ templates.

#### 2.2.4 Classes as types

A class defines a datatype. In particular, it is clear that it represents an algebraic datatype when we move labels to constructors and different alternatives are collected in an union type. In the presence of inheritance, type definitions are expanded. Using Haskell  notation, the previous classes can be translated to the following types, where constructors names are prefixed by the class name to avoid name clashing:

```
data Point1 = Point1Cartesian (Real, Real)
data Point2 = Point2Cartesian (Real, Real) | Point2Polar (Real, real)
data Segment = SegmentSeg (Point1, Point1)
data Stack a = StackContents (Int, Seq a)  % With an adequate definition of Seq
data Tree a = TreeEmpty | TreeNode (Tree a, a, Tree a)
data ColouredPoint = ColouredPointCartesian (Real, Real, Colour)
data ColouredSegment = ColouredSegmentSeg (ColouredPoint, ColouredPoint)

```

### 2.3 Predefined classes and relationships

The SLAM system includes a good number of predefined classes as well as some predefined relations between them. Examples of predefined classes are numbers, booleans, characters, dates, angles, strings, records, sequences, lists, dictionaries, etc. An example of the abstract class hierarchy comes from the Collection class. The following figure shows the behavioural organization of these classes, where the layout reflects inheritance:

| Collection |
| --- |
|  | TravCollection |  |  | Traversable collections |
|  | FiniteTravCollection |  |  | Finite traversable collections |
|  |  | Set |
|  |  | Multiset |
|  |  | IndexedCollection |  | Indexed collections. They are traversable |
|  |  |  | OrderedIdxCollection | As above, but respecting the order of elements |

### 2.4 Traversals

Any class that represents a collection of elements could specify a *traversal*. A traversal is either a *simple enumeration* or a sequence of traversals.

* A *simple enumeration* of a class is a triple (first, next, inside), where first is a class function that returns the initial element of the traversal, next is a class function that eliminates the first element and prepares it to give the following element of the traversal, and inside is a class boolean function indicating if the element already belongs to the traversal.

+ Arithmetic ranges \[n..m\] are objects in SLAM, and can be seen as examples of simple traversals: first returns n, next consist in adding one to the lower limit \[n+1..m\], and inside is the function that checks if the lower limit is lesser or equal than the upper one n $``$ m.
    + A single element x is also a trivial example of a simple enumeration.
    + A sequence is another example of single enumeration: first returns the first element of the sequence, next eliminates the head of the sequence and inside decides if there are still elements in the sequence.

As soon as a class has a traversal defined (i.e. is an instance of the TravCollection class) an object of the class can be used in the place of a traversal.
* A general traversal is a non empty sequence of traversal: \[tr1, …, trn\]. Traversals in the sequence can be of any class and the order is relevant, because the structure will be traversed using this order. Typically, it contains simple traversals or objects of TravCollection classes. There is just one traversal per class, although several rules to define it can be used depending on the different shapes of the attributes. Traversals are specified in the following way:

where Shape ($`\overline{x}`$) indicates the shape of the object, and Traversal is a simple or general traversal.

An example of a traversal of a binary tree is the element at the root (a simple enumeration), the left subtree (that can be traversed by the same method) and the right subtree.

| Empty $``$ |
| --- |
| Node (ls, root, rs) $``$ \[root, ls, rs\] |

Notice that changing the order of this definition means a different way to traverse the tree (for instance, first traversing the left subtree, then the root, and finally the right subtree by using the traversal \[ls, root, rs\]).

A traversal can be interpreted as a way to generate a scheme of code to traverse the data. A simple enumeration can be translated into a single loop or a linear recursion, while a general traversal is moved to a multiple recursive code (even with parallel execution).

### 2.5 Class Operations

SLAM has a clear functional flavour, so class operations (methods) can be represented by functions. For the shake of simplicity some syntactical distinctions have been introduced to distinguish standard object oriented aspects, although they can be inferred by the system. The classification of operations is the following:

* *Object constructors.* An object constructor is a function designed to create new instances of a class. An object constructor declaration in class Class consists in the name of the constructor333There are no restrictions on constructor names., and the argument types:
constructor f : $`\overline{T}`$    means a function:    function f : $`\overline{T}`$ $``$ Class
* *Object observers.* Observers allow to access properties of an object without modifying it. An observer of class Class of the form:
observer f : ($`\overline{T}`$$``$ $`R`$    means a function:    function f : (Class,$`\overline{T}`$$``$ $`R`$
* *Object modifiers.* Modifiers are designed to modify the value of an object. From the functional point of view a modifier of class Class of the form:
modifier f : ($`\overline{T}`$)    means a function:    function f : (Class,$`\overline{T}`$$``$ Class
* *Friend functions.* They are functions that involve two or more objects of the class and they have not special decoration to be declared.

Function invocation for constructors, observers and modifiers is done via the usual dot notation, i.e. function f of class Class is called in the object obj by the expression obj.f ($`\overline{a}`$) or, in case of ambiguity, by obj.Class:f ($`\overline{a}`$).

In SLAM a function is specified by a set of *rules*. Every rule involves a *precondition* that indicates if the rule can be apply, a *function call scheme*, and a *postcondition* that relates input and output.

The general form of a function specification is the following:

| pre :- $`P(\overline{x})`$ |
| --- |
| f ($`\overline{a})`$ |
| post :- $`Q(\overline{x},\text{result})`$ |

where $`P(\overline{x})`$ is a SLAM formulae involving variables of the arguments ($`\overline{a}`$) and $`Q(\overline{x},\text{result})`$ is another SLAM formula. The variable (and reserved word) result is always used to represent the computed value of the function. The formal meaning of that specification is the assertion of the following fact:

$$P(\overline{x})Q(\overline{x},𝖿(\overline{a}))$$

Although SLAM formulas and expressions will be defined in detail later the reader can accept some examples on class Point:

| constructor PointAt : (Real,Real) |
| --- |
| pre :- true |
| PointAt (x, y) |
| post :- result = Cartesian (x, y) |

| observer CoordX : () $``$ Real |
| --- |
| pre :- true |
| Cartesian (x,y).CoordX () |
| post :- result = x |

| function Distance : (Point,Point) $``$ Real |
| --- |
| pre :- true |
| Distance (Cartesian (x1,y1), Cartesian (x1,y2)) |
| post :- result = sqrt (sqr (x1 - x2) - sqr (y1-y2)) |

As in VDM explicit function definitions are allowed. Even more, unconditionally true preconditions can be skipped what provides more concise and readable specifications.

| observer CoordY : () $``$ Real |
| --- |
| Cartesian (x,y).CoordY () = y |

| modifier MoveLeft : (Real) |
| --- |
| p.MoveLeft (d) |
| post :- (Distance (result, p) = d) and (p.CoordY() = result.CoordY()) |

A function specification only indicates the relationship between the result and the arguments, but not necessarily a method to compute the function. Such a method is called a *solution* in SLAM terminology. A solution always gives a *computable expression* to the function (i.e. to the result variable in the postcondition). Next section will describe exactly what is a computable SLAM expression.

In those cases where the specification is not a solution, it can be specified in the following way:

| function f : ($`\overline{T}`$$``$ Class |
| --- |
| pre :- $`P(\overline{x})`$ |
| f ($`\overline{a}`$) |
| post :- $`Q(\overline{x},\text{result})`$ |
| $``$ Solution $`(\overline{x}`$) |

where Solution is a computable SLAM expression. For instance, we could have:

| modifier MoveLeft : (Real) |
| --- |
| p.MoveLeft (d) |
| post :- (Distance (result, p) = d) and (p.CoordY() = result.CoordY()) |
| $``$ Cartesian (-p.CoordX (), p.CoordY ()) |

### 2.6 SLAM formulae and quantifiers

SLAM formulas are basically logic formulas using the usual logical connectives (and \- conjunction, or \- disjunction, not \- negation, implies \- implication, and equiv \- equivalence), predefined and user defined functions and predicates, and *quantifiers*.

SLAM formulas are typed in a similar way than other expressions. In fact, expressions and formulas share the syntax – every formula is an expression of type boolean.

SLAM expressions can combine objects with its own operations. Operations can be combined in any consistent way to produce new expressions. Expressions can use quantifiers of adequate types. Quantifiers are a key feature in SLAM and extend the notion of quantifier in logic. Quantifiers can compute not only the truth of an assertion but also any other value. Moreover quantifiers can be applied to any *collection* object. Examples of collections are sets, sequences, multisets, lists, trees, etc. The basic reading of a quantifier is the traversal of a collection object in order to apply an operation to all the elements in the collection. Therefore, the components of a quantifier are:

* The quantifier itself that generalizes a basic binary operation.
* The description of the collection which is traversed.
* A filter (boolean expression) that indicates which elements in the collection are involved in the quantification. Filters are introduced to avoid the generation of many intermediate objects.
* The quantified expression

A quantifier is written in the following way:

$`\mathrm{\Xi }`$ x in D $`|`$ filter (x) $``$ expression (x)

where $`\mathrm{\Xi }`$ is the quantifier symbol (that indicates the meaning of the quantifier), D is a collection where the quantifier ranges, x is the quantified variable, filter is a boolean expression that restricts the elements of D that are taking into account for the quantification and expression is a function to interact with the quantification.

We describe some predefined quantifiers, one for each kind, although SLAM includes all used in logic and many more:

(exists or $``$): Decides if there is an element in D where filter is true, verifying expression. It is a generalization of the logical disjunction.

(forall or $``$): Decides if all the elements in C where filter is true, verify expression. It generalizes the logical conjunction.

(sum or $`\mathrm{\Sigma }`$): Sums all the values expression (x) where x ranges in the elements of D where filter is true. Obviously, the addition is generalized by this quantifier.

(prod or $`\mathrm{\Pi }`$): Multiplies all the values expression (x) where x ranges in the elements of D where filter is true (by generalizing multiplication).

(count or $`𝒩`$): Counts the elements in D where filter is true, verifying expression.

(select of $`^{}`$): Returns any element in D where filter is true, verifying expression.

(max or $``$): Returns the maximum of all the values expression (x) where x ranges in the elements of D where filter is true.

(maxim or $`^{}`$): Returns the value y such that expression (y) is the maximum of all the values expression (x) where x ranges in the elements of D where filter is true.

(min or $`\mu `$): Returns the minimum of all the values expression (x) where x ranges in the elements of D where filter is true.

(minim or $`\mu ^{}`$): Returns the value y such that expression (y) is the minimum of all the values expression (x) where x ranges in the elements of D where filter is true.

(filter or $``$): Returns an element of the same class of D but eliminating the elements that verify expression.

(map or $`𝒞`$): Returns an structure with the elements expression (x) such that x ranges in the elements of D where filter is true.

(seq or $`𝒮`$): Constructs a sequence with indexes in $`D`$ and elements the values of expression (x).

#### 2.6.1 Computable SLAM expression

Any SLAM expression can be computed provided that quantifiers are applied to a FiniteTravCollection class. A FiniteTravCollection is a collection class whose instances can be traversed and they have a finite number of elements.

### 2.7 Asserting properties

The SLAM compiler is designed to produce executable and readable imperative code. One of the main features of the resulting code is that it contains debugging annotations, similar to the assert directive of C. The main idea is to include assertions to check pre and postconditions. However, this is not always possible. SLAM can generate checking code for formulas involving quantifications over objects that can be finitely traversed, although it is not necessary - for postconditions - that they assign a value to result.

When a formula cannot be checked completely, the user (maybe later with the help of the SLAM compiler) can indicate three possible situations. For simplicity we apply them to the postcondicion but the same annotations can be done for the precondition.

* The full formula can be checked. This is done by adding the keyword check to the formula. This is the case when the specification is yet a solution and in this case no annotation is needed.
function f : ($`\overline{T}`$$``$ Class  pre :- $`P(\overline{x})`$  f ($`\overline{a}`$)  post :- check $`Q(\overline{x},\text{result})`$
* Just a part of the formula can be checked. This means that it is a part of a conjunction, so we assume that first part of the formula cannot be checked, and the second one is marked by the keyword and\_check.
function f : ($`\overline{T}`$$``$ Class  pre :- $`P(\overline{x})`$  f ($`\overline{a}`$)  post :- non-checkable-property($`\overline{x}`$, result) and\_check checkable-property($`\overline{x}`$, result)
* The formula cannot be checked at all or the part that can be checked is not significant. In this case, the user can provide an approximation of the property that is checkable by placing it after the keyword either\_check.
function f : ($`\overline{T}`$$``$ Class  pre :- $`P(\overline{x})`$  f ($`\overline{a}`$)  post :- non-checkable-postcondition($`\overline{x}`$, result) either\_check checkable-approximation($`\overline{x}`$, result)

### 2.8 An additional example

Let us show a more complete but simple example of a SLAM specification. The problem is to handle transactions between saving banks. The input is a collection of transactions (with the source bank, the destination bank and the amount) and the collection of bank names. The function to specify must compute the final profit/debit for each bank.

| class Transaction is |
| --- |
| public tran & {source : String, destination : String, amount : Real} $``$ Transaction |

| class Bank is |
| --- |
| public bank & {name : String, amount : Real} $``$ Bank |
| constructor MakeBank : (String,Real) |
| MakeBank (n, a) = {n, a} |

| class CTransaction is |
| --- |
| ctran & Seq (Transaction) $``$ CTransaction |

### 2.9 Additional features

SLAM includes some other features that are quite convenient for program specification. However, due to the lack of space we have omitted those characteristics that are less interesting for the purpose of this paper. Among them we can mention: *Selectors*, that extend patterns for hidden constructors of classes, *Internal laws*, to simplify the data stored in a class after any operation, a broad notion of visibility in case of aggregation, etc.

## 3 Compiling SLAM programs

### 3.1 Compiling SLAM to an imperative object oriented language

One of the main features of the SLAM is that it is able to generate code from a specification. We will use C++ () as the target language. However the ideas are applicable to any language with similar characteristics (Java, Smalltalk, etc.). In this section we only sketch the main ideas for the compilation because this is not the main goal of the paper. The basis for the compilation are:

* SLAM classes are translated to C++ classes.

An SLAM class defines a declarative type via its attributes. This type is translated into an imperative type. The C++ class contains a single attribute of this type. The construction of an imperative type from a declarative one is a key feature for the compilation. Constructors are translated to records, alternative definitions are moved to union types while recursive definitions need the inclusion of a pointer.
* SLAM class relationships are almost mimic by C++ class relationships.

+ Aggregation is already included in object oriented languages.
    + Most of the power of inheritance on SLAM is included in C++, except the inheritance modification of the state. Attribute constructor extension (or record extension) can be modelled by C++ attribute extension (i.e. additional attributes can be supplied in the subclass), while state overriding can be implemented by attribute redefinition444In C++, when a subclass declares an attribute with the same name of an attribute of the superclass, this last one is hidden by the newest..
    + Association can be simulated by inheritance and/or the use of templates.
* SLAM predefined classes are implemented by specifically designed C++ classes, although some of them need a special treatment by the compiler.
* SLAM functions are implemented by C++ methods in traversable classes. The SLAM classification of operations are easy to map into C++ classification.
* Traversals are implemented by including the operations first, next, and inside as class methods. Quantifiers are implemented by adequate loops.
* An additional operation serialize is included in all the classes to store an element into a file using the XML format. This operation is also automatically generated.

In our previous example, we can obtain automatically a C++ code similar to the following one555Some parts have been skipped, and some simplifications like using arrays as the Seq implementation have been included to improve readability.:

```
// in file transaction.h
class Transaction {
 public:
   String source;
   String destination;
   float amount;

   void serialize ();
};

```

```
// in file bank.h
class Bank {
  public:
    String name;
    float  amount;

    void Bank (String n, float a) {
      name = n;
      amount = a;
    }
    void serialize ();
};

```

```
// in file ctransaction.h
class CTransaction {
  public:
    void FinalAmount (
      String banks [MaxBanks],
      Bank result [MaxBanks]);
    void serialize ();

    Transaction trans [MaxTrans];
};

```

```
// in file ctransaction.cpp
void CTransaction::serialize () {
...
}

void CTransaction::FinalAmount (
  String banks [MaxBanks],
  Bank result [MaxBanks])
{
  pre-check (FinalAmount (banks, MaxBanks));
  for (int i = 0; i <= MaxBanks; i++){
    float amount = 0;
    for (int j = 0; j <= MaxTrans; j++){
      if (trans[j].source == banks [i])
        amount =+ trans[i].amount;
      else if (trans[j].destination == banks[i])
        amount =- trans[i].amount;
    }
    result[i] = new Bank (banks [i], amount);
  }
  post-check (FinalAmount
                (banks, MaxBanks, result))
}

```

This automatically generated code is not necessarily intended to be an efficient code. In fact, it could be considered a prototype code, although in many cases the code is good enough. In those situations, or even in situations in which SLAM cannot generate code, the user can modify it and write an optimizing code.

In our previous example, the programmer can decide that it is better to traverse first the transaction collection and then search the name of the banks to update the result. The new code is:

```
void CTransaction::FinalAmount (String banks [MaxBanks],
                                Bank result [MaxBanks]) {
  pre-check (FinalAmount (banks, MaxBanks));
  for (int i = 0; i <= MaxBanks; i++){
    result[i].name = banks [i];
    result[i].amount = 0;
  }
  for (int j = 0; j <= MaxTrans; j++){
    for (i = 0; i < MaxBanks; i++) {
      if (trans[j].source == result [i].name)
        result[i].amount =+ trans[i].amount;
    }
    for (i = 0; i < MaxBanks; i++) {
      if (trans[j].destination == result [i].name)
        result[i].amount =+ trans[i].amount;  // There is a bug here
    }
  }
  post-check (FinalAmount (banks, MaxBanks, result))
}

```

Notice that the code contains a bug when the destination bank is found. Instead of decreasing the amount it is increased. Program assertions remain valid, so the bug will be detected when the program is executed in the debug mode.

### 3.2 Compiling SLAM to Prolog

More relevant for the purpose of the paper is the compilation of SLAM programs and assertions into a Prolog piece of code.

We use the Ciao/Prolog system  as the target language. The main reasons are our knowledge of the system and our easy access to the Ciao/Prolog system developers, the availability of some higher order features that simplify the implementation of quantifiers, and the existence of an interface to connect C/C++ and Prolog programs. Anyway, the most important ideas presented here are independent of the Ciao/Prolog system and are applicable to any other Prolog system.

We have already explained that the semantics of classes are algebraic types. Instances of classes will be translated using Prolog functors as data constructors. This is the usual way in which other declarative languages translates algebraic types into Prolog. The name of the class is added to the name of the constructor in order to avoid clashing in the presence of inheritance.

A formal specification of the translation of function definitions is given in figure 1. Every function is compiled into three predicates that implements different functionalities. For every function $`f`$ with arity $`n`$ we will have the predicate ’sol-$`f`$ that implements the function $`f`$. The arity of this predicate is $`n+1`$ where $`n`$ is the arity of the function (remember that member functions in SLAM are functions with an element of the class as the first argument). Predicates ’pre-$`f`$ and ’post-$`f`$ will implement the *checking* predicates of the pre and postconditions of the function $`f`$.

The complete translation function translate (see figure 1) accepts a SLAM program as argument and returns a Prolog program. The definition uses several auxiliary functions.

* trans\_rule accepts a rule and the class where the rule appears and returns three Prolog clauses: for ’sol-$`f`$, ’pre-$`f`$ and ’post-$`f`$. In the definition a rule is represented by a record with six fields: class (the class where it is defined), fname (function name), args (arguments), sol (the solution proposed by the rule), pre (checkable part of the precondition), and post (checkable part of the postcondition).
* trans\_sol, trans\_pre, and trans\_post are responsible for producing clauses for the function implementation and for checking the pre and postconditions.
* trans\_expr produces Prolog atoms in order to translate a SLAM expression. trans\_expr($`e`$, X, $`C`$) ensures that the Prolog variable X stores the computation of the expression $`e`$ in the class $`C`$.
* trans\_inh is designed to produce the clause associated to an inherited function $`f`$ definition in class $`C`$ checked by miss. defines returns the ancestor class where a function is declared (see below for further details).
* trans\_term translates a term in a class into the corresponding Prolog representation (following the name policy described above).

In the compilation scheme presented in figure 1 $`c`$ represents an attribute constructor while $`f`$ represents a function. $`aC`$ *produces* all possible skeletons of terms in class $`C`$. log\_op is any SLAM logical operator computed in Prolog by the corresponding log\_op predicate666Notice that they cannot be implemented by the similar Prolog operations (conjunction $``$ ,, etc.) because SLAM boolean functions compute false as a valid result. We leave their definitions as a trivial exercise.. trans\_predefined contains a Prolog implementation of SLAM predefined operations. Anyway the scheme deserves a deep discussion on some aspects:

It is important to note that the same predicate name is used to compute the same function in all the classes coming from the ancestor class. Some few words are needed to justify this decision and to show that it really handles the overloading produced by the use of inheritance. As Prolog has no types, a predicate can be applied to any number of functors on the top of arguments. Remember that attribute constructors in different classes have different names. If $`f`$ is a member function of $`C`$ and the functions is applied to an expression $`e`$ the generated Prolog atoms are:

$`\text{trans\_expr}(x,\text{Y},C)`$, ’sol-$`f`$’(Y,R)

Notice that the clauses of ’sol-$`f`$ includes all the definitions of $`f`$ in the complete class hierarchy, so it does not matter the exact subclass $`A`$ of $`C`$ which $`x`$ belongs to. As Y will not contain free variables and the attribute constructors in all the classes have different names, only the adequate original rule is applicable. A similar approach is used for ’post-$`f`$ and ’pre-$`f`$.

Patterns are translated into Prolog patterns, so parameter passing is handle by unification. This use of unification is quite efficient in Prolog because our programs only use the *read mode* of the underlying WAM machine. Function composition is handled by flattening the functional structure and using auxiliary variables to connect the predicates.

There are additional technical details that must be solved. One appears when a function in class $`A`$ is fully inherited from a class $`C`$, i.e. there are no rules for $`f`$ in $`A`$. As the attribute constructors in both classes may be different, we need to add a clause to transforms the arguments to have the constructors in $`C`$ and then call recursively the same predicate. Suppose that the attribute constructor in $`C`$ is c and the attribute constructor in $`A`$ is c’ with possibly more attributes. The generated clause is:

’sol-$`f`$’(c’($`\overline{x}`$,$`\overline{y}`$), R) :-  ’sol-$`f`$’(c($`\overline{x}`$), R).

The second one is how to compile a function call with explicit indication of the class. This expression could involve a type casting from an argument to an ancestor class. For each class $`C`$ we could generate a predicate ’to-$`C`$ that transforms all the elements of any successor class $`A`$ into $`C`$. A call of the form obj.$`C`$:f ($`\overline{x}`$) is translated into the atoms

’to-$`C`$’(obj,Obj), ’sol-$`f`$’(Obj,$`\overline{x}`$,R)

Notice that the dispatch table used for the compilation of inheritance is simulated here by the use of different functors names (keys into the table) as well as the unique predicate with all the possible implementations of the function (the table itself). One can argue that in case of an intensive use of inheritance this huge predicate can be a source of inefficiency. Remember that the Prolog program is just used for debugging, so efficiency is not a crucial point. On the other hand, this possible source of inefficiency is partially solved by the indexing included in WAM-based Prolog implementations.

Translation of traversals and quantified expressions follow an interesting approach. The trans\_trav translation scheme is applied for any class C implementing the TravCollection and consists in the generation of a predicate in. The first argument of the predicate is the traversable object, the second argument *produces* by backtracking all the values in the collection. A simple traversal is translated in this way:

| in(O,X) :- first(O,X). |
| --- |
| in(O,X) :- next(O,O2), inside(O2), in(O2,X). |

while a traversal definition using a sequence of traversals is translated into several clauses, one for each traversal in the sequence:

| in(\<\<shape\>\>,X) :- in(\<\<tr1\>\>,X). |
| --- |
|  |
| in(\<\<shape\>\>,X) :- in(\<\<trn\>\>,X). |

A trivial translation of a quantifier definition is got by using the following predicate quantifier. Ciao/Prolog allows a special syntax f ($`\overline{𝖠}`$) := Expr :- condition to compute the function f as the expression Expr provided that condition holds. The Ciao/Prolog higher order contains the usual higher order functions, like `~`foldr($`f,s,[x_1,\mathrm{},x_n]`$) that computes the value of $`f(x_1,f(x_2,\mathrm{}f(x_n,s)\mathrm{})`$. There is also a special syntax for lambda expressions (called predicate abstractions) $`\backslash `$($`\overline{𝖷}`$, R) :- Expr, where R stores the computed expression Expr applied to the arguments $`\overline{𝖷}`$. We show the implementation of some quantifiers as an example.

| quantifier(Binop,Seed,Collection,Filter,Expression) := `~`foldr(Binop,Seed,L) :- |
| --- |
|  | findall(Y,(in(Collection,X),Filter(X),Expression(X,Y)),L). |
| ’quan-all’(Collection,Filter,Expression, R) :- |
|  | R = quantifier(log\_and,true,Collection,Filter,Expression). |
| ’quan-sum’(Collection,Filter,Expression, R) :- |
|  | R = quantifier(+,0,Collection,Filter,Expression). |
| ’quan-map’(Collection,Filter,Expression, R) :- |
|  | R = quantifier($`\backslash `$(X, L, R) :- R = \[X|L\],\[\],Collection,Filter,Expression). |

In some cases the filter predicate can generate values in a very efficient way and a more efficient translation could be (Filter(X), in(Collection,X)) in the condition of the “findall construct. In principle, we have not information for choosing between both alternatives, unless we use some techniques borrowed from program analysis.

It is worth mentioning that, by this translation, it will be clear that the SLAM selection quantifier provides the full power of Prolog search, what enhances the expressive power of SLAM.

Notice that the checkable part of function pre and postconditions are translated also into special predicates. The only tricky question is the use of the same argument patterns of the function instead of the variables to ensure the adequate parameter passing even for the conditions.

The last part of the translation that must be explained is the goal of the $`\text{trans\_read}(C)`$ clauses. For each class $`C`$ a predicate with name ’read-C is defined in order to read an element of class $`C`$ from a class. The format of the data in the file is exactly the same that is stored by the counterpart operation (serialize) of the C++ class for $`C`$. Due to the lack of space, we omit the definition although it is an easy exercise.

Let us show the Prolog code for our example. Again we have omitted some parts, and included some simplifications to make it more readable, like the implementation of sequences as lists or the inclusion of intermediate predicates to compute the quantified expressions.

| amount(tran(S,D,A),A). |
| --- |
| ’sol-MakeBank’(N, S, bank(N,S)). |
| sumSource(Ctr,N,V) :- ’quan-sum’(CTr,($`\backslash `$:(tran(S,D),R) :- S == N -\> R = true; R = false), amount, V). |
| sumDest(Ctr,N,V) :- ’quan-sum’(CTr,($`\backslash `$:(tran(S,D),R) :- D == N -\> R = true; R = false), amount, V). |
| ’sol-FinalAmount’(CTr, Banks, Result) :- |
|  | ’quan-map’(Banks, true, $`\backslash `$ | (N, R) :- |
|  |  | sumSource(CTr, N, A1), sumDest(CTr, N, A2), A is A1 - A2, |
|  |  | R = ’sol-MakeBank’(N,A)). |
| ’pre-FinalAmount’(CTr, Banks) :- Length(Banks, L), L \> 0. |
| ’post-FinalAmount’(CTr, Banks, Result, Post) :- |
|  | Length(Banks, L1), Length(Result, L2), L1 == L2, |
|  | all(1..L1, true, ($`\backslash `$(I, R) :- | nth (Result, I, bank (N, A)), nth (Banks, I, N), |
|  |  | sumSource (CTr, N, A1), sumDest (CTr, N, A2), |
|  |  | A == A1 - A2), true). |
| in(\[X|\_\], X). |
| in(\[\_|L\], X) :- in(L, X). |
| in(N .. M,N). |
| in(N..M,R):- N \<= M, NN = N+1, in(NN..M, R). |

It is obvious that the transformation can be improved avoiding several sources of inefficiency: generation of useless intermediate variables, predicate calls that can be folded, construction of the result in the head of the clause, etc. However, it is worth mentioning that the Ciao/Prolog system includes several optimizations based on partial evaluation and global analyses in the compilation process that can solve part of the inefficiencies. The system can eliminate part of the conditions to be checked ().

## 4 Execution of assertions

We have developed a C++ library called "check.h" including the macros needed to execute the assertions. Basically, the library contains three operations: pre-check (function name, arguments), to check preconditions, post-check(function name, arguments, result), to check postconditions, and post-return-check(function name, arguments, result), to check a postcondition and return a value.

The interface between C/C++ and Prolog is very primitive. A string containing the goal is used to call the Prolog program. The arguments (and the result, in the case of the postconditions) are stored in a file file via the serialize operation. A process is spawned to run the Prolog program, which reads from the file the arguments/result and calls the corresponding predicate. The pseudo-code for post-return-check (fname, $`\overline{args}`$, result) is the following:

| r = result; |
| --- |
| fd = fopen (file); |
| $`arg_1`$.serialize (fd); |
| ⋮, |
| $`arg_n`$.serialize (fd); |
| r.serialize (fd); |
| fclose (fd); |
| fork (prolog (’post-fname’); |
| assert (return code of process); |
| return r; |

The other cases are analogous. We only need to add the Prolog program two clauses for each function $`f`$ of the form:

| ’pre-f’ :- ’read-$`C_1`$’(A1), …, ’read-$`C_n`$’(An),’pre-f’(A1, …, An). |
| --- |
| ’post-f’ :- | ’read-$`C_1`$’(A1), …, ’read-$`C_n`$’(An),’read-$`C_r`$’(Result), |
|  | ’post-f’(A1, …, An, Result). |

The use of the file for exchange information between the C++ program and the Prolog program can be optimized using a pipe to link the processes. As a pipe is handled as a file, there is no significant difference w.r.t the previous scheme.

There is an alternative possibility. First of all, we modify serialize to construct a Prolog representation of data as a string. Then a Prolog goal of the form:

| assert (arguments ($`arg_1`$.serialize (), …$`arg_n`$.serialize (), result.serialize ()), |
| --- |
| arguments (A1, …, An, Result), ’post-f’ (A1, …, An, Result). |

is used to call the Prolog engine.

The Prolog *assert* is needed to ensure that the arguments are compiled. The main problem with this approach is that when the data are large, the string representation of the goal is longer than the accepted size by the Prolog compiler.

Additionally, the debugging execution produces a report on the pre/postconditions checked, indicating those conditions that where marked as a subformula (and\_check) or alternative condition (either\_check) of the full pre/postcondition.

## 5 Future work and Conclusion

We have presented the validation facilities of the SLAM system. From a high level specification the system generates code to execute the system including assertions to check pre and postconditions of the program operations. These high level logical formulae are compiled into Prolog and the resulting program is responsible for checking them. The compiled SLAM program is linked with the assertion Prolog program to achieve the debugging facilities that are specially useful when the programmer decides to modify the automatically generated code.

The overall efficiency is acceptable. The execution of the program in the debug mode needs between 3-4 times the execution of the program itself.

The SLAM project is at the early stages of its development. The specification language is not fully defined yet and the system (environment, compilers, libraries, etc.) is under development. We plan to have a prototype with the debugging facilities by the date of the workshop.

The SLAM project and its debugging facilities seem to be a very useful tool to develop high quality programs, i.e. error free with respect to the specification, clean, easy to read and manipulate to achieve modifications either in the specification or in the generated code, fully documented and including high level declarative debugging facilities to allow optimizations in a reliable way.

The debugging facilities can be used for other purposes. It is easy to modify the system to allow assertions along the code, for instance to check loop invariants.

For the behaviour of the system is case of failure of the debugging assertions we rely on the underlying debug facilities (the effect of assert in C++ in our case). Of course it is possible to modify this behaviour to use failures to locate more precisely the bug and the wrong function in the vein of algorithmic debugging . More precisely, when a function call violates its postcondition, function invocations inside the code are checked. Those that have an incomplete postcondition (i.e. annotated as and\_checkor either\_check) are on suspicion of wrong behaviour.

Another relatively easy extension is to use the SLAM debugging facilities for program validation by testing automatically sequences of data designed to cover all the cases.