\section{Logic variables}\label{sec-funvar} As previously presented, there is two kinds of memory models. One based on variables, as in the Hoare model see section~\ref{sec-hoare} and the other based on the representation of the heap, as the Store model (see section~\ref{sec-store}) and the Runtime model (see section~\ref{sec-runtime}). The second kind of memory model is more expressive since it can handle dereferencing of pointers, and addresses of variables. The cost is quite heavy: the generated formula are largest. The ideal is to benefit this expressiveness only for the variables involved in dereferencing of pointers and address management, in other words the variables such as their addresses are computed. For the other variables, variables such as their addresses are never computed (notice that they behave as functional or logical variables) they can be handled by a model {\it � la} Hoare. This kind of optimization, with a generous definition of optimization, is quite current in memory model specifications and implementations. In the WP, the model {\it � la} Hoare is the Logicvar model and to make it cooperate with a based on heap memory model, one has to set the {\tt -wp-logicvar}. A variable translated in Logicvar has in $\cal{L}$ a logic type then it is translated as \textsf{ACSL} data (see section~\ref{sec-acsl}). Let us consider this example: \begin{ccode} typedef struct S { int a; int * p; }; struct S s; struct S r; /*@ ensures \result == {s \with .a = (int)4 }; */ struct S ret_struct(void) { struct S * ps; r.a = s.a ; s.a = 4; ps = &r; return r; } \end{ccode} This example has a semantics only in a based on heap memory model, because the address of \whyinline{r} is taken. Computing the proof obligation associated to the post-condition with the memory model Store in the WP plug-in gives: \begin{whycode} goal store_full_ret_struct_post_1: forall m:data farray. forall ta:int farray. global(ta) -> (ta[X_ps] = 0) -> is_fresh(m, ta, X_ps) -> is_fresh( m[addr(X_r,0) <-encode(int_format,decode(int_format,m[addr(X_s,0)]))][addr(X_s, 0) <-encode(int_format,4)][addr(X_ps,0) <-encode(addr_format,addr(X_r,0))], ta_2[X_ps<-1][X_ps<-0], X_ps) -> Eqrec_S( decode(Cfmt_S, access_range( m[addr(X_r,0) <-encode(int_format,decode(int_format,m[addr(X_s,0)]))][ addr(X_s,0) <-encode(int_format,4)][addr(X_ps,0) <-encode(addr_format,addr(X_r,0))],zrange(X_r,0,2))), decode(Cfmt_S, access_range( m[addr(X_r,0) <-encode(int_format,decode(int_format,m[addr(X_s,0)]))][ addr(X_s,0) <-encode(int_format,4)][addr(X_ps,0) <-encode(addr_format,addr(X_r,0))],zrange(X_s,0,2)))[F_a <-encode(int_format,as_int(sint32_format,4))]) \end{whycode} For each variable, a location is created into the heap. The local variables trigger two local allocations for their locations. The three assignments take place in the same $\cal{L}$ array, the store. Unless expressing the address taken of \whyinline{r} and the address assignment \whyinline{ps= &r;}, this is uninteresting to use the Store model. Moreover, this assignment is heavy noise for the automatic provers. Then, using Logicvar, the WP plug-in generates the formula: \begin{whycode} goal store_ret_struct_post_1: forall m:data farray. forall s:data farray. Eqrec_S( decode(Cfmt_S, access_range( m[addr(X_r,0)<-encode(int_format,decode(int_format,s[F_a]))], zrange(X_r,0,2))), s[F_a<-encode(int_format,4)][F_a <-encode(int_format,as_int(sint32_format,4))]) \end{whycode} Since the assignment \whyinline{ps= &r;} is {\it mute} for the post-condition, the WP plug-in ignores it. Hence, only \whyinline{r} is represented into the memory, the other variables are handled as logic variables.