220 4964 <67dced99-d566-4082-94e1-2f831119e1cf@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: contract programming: invariants or axioms?
Date: Mon, 10 Jun 2013 10:22:39 -0700 (PDT)
Lines: 199
Approved: news@gmane.org
Message-ID: <67dced99-d566-4082-94e1-2f831119e1cf@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_543_24950661.1370884959523"
X-Trace: ger.gmane.org 1370884962 18401 80.91.229.3 (10 Jun 2013 17:22:42 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Mon, 10 Jun 2013 17:22:42 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDT2DGOJ34DBBYEW3CGQKGQEFPM4XBA@isocpp.org Mon Jun 10 19:22:44 2013
Return-path: <std-proposals+bncBDT2DGOJ34DBBYEW3CGQKGQEFPM4XBA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vb0-f72.google.com ([209.85.212.72])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDT2DGOJ34DBBYEW3CGQKGQEFPM4XBA@isocpp.org>)
	id 1Um5nm-0002lN-7q
	for gclcip-std-proposals@m.gmane.org; Mon, 10 Jun 2013 19:22:42 +0200
Original-Received: by mail-vb0-f72.google.com with SMTP id p12sf5812343vbe.3
        for <gclcip-std-proposals@m.gmane.org>; Mon, 10 Jun 2013 10:22:41 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=x-beenthere:date:from:to:message-id:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-google-group-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe:content-type;
        bh=n8z8Nr5dGsoiV5huH4BNE9GjHSyn9PdxGk4DZ5teYtg=;
        b=rcKvxy6MXM3GTNMgPTinoSl/mOA+syo3ow2qwSgLH+EbdmlnHn5u4tyXtMnU8lixRw
         vf2hff69s3D8t/XXH1XiAuyXm2Q9aT6OVHPVeY/b9GWfKrSx1W76nywVuweeKdybeQMf
         gTiQQAk60VMqkouzaBAW8GNyg1phg07TxjvNIRN7I9uPa1khOX/nRn199ZqvOcOB2xBe
         G08TH08m/8o+iWleDLLLP9sbvl7MO4LTGHN5HvRuHLgfDu2WbVDEo1cF6AIdFTje4XyG
         YytRy3JuONSi+yfsEHeTFRTcTXgbW/px5Ho6ccsbFO+ofgybmUrWwCVwxvNEb/32iLd/
         om2Q==
X-Received: by 10.224.42.141 with SMTP id s13mr8856871qae.3.1370884961317;
        Mon, 10 Jun 2013 10:22:41 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.83.102 with SMTP id p6ls384767qey.63.gmail; Mon, 10 Jun
 2013 10:22:40 -0700 (PDT)
X-Received: by 10.49.62.168 with SMTP id z8mr496887qer.11.1370884959962;
        Mon, 10 Jun 2013 10:22:39 -0700 (PDT)
X-Original-Sender: akrzemi1@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post?hl=en>,
 <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?hl=en&topic=25838>,
 <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe?hl=en>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe?hl=en>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:4964
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/4964>

------=_Part_543_24950661.1370884959523
Content-Type: text/plain; charset=ISO-8859-1

Hi Everyone,
I wanted to share, and run through the community, one thought about 
contract programming features. Namely, that axioms (like those in concepts) 
are a superior alternative to invariants.

One of the goals of contract programming support in C++ would be to assist 
with static analysis. For instance, given the following 
pre-/post-conditions for *std::optional*
*
*
*T& optional<T>::operator*()
precondition{ bool(*this) };

T& optional<T>::operator=(T&&)
postcondition{ bool(*this) }; *

Compiler should be able to deduce the following:

// warning: precondition likely not met
*void apply(function<void(int)> f, optional<int> i)
{
  f(*i);
}
*
// safe (checked manually):
*void apply1(function<void(int)> f, optional<int> i)
{
  if (i) { f(*i); }
}*

// safe (postcondition matches the precondition):
*void apply2(function<void(int)> f, optional<int> i)
{
  i = 0;
  f(*i);
}*

// safe (preferable):
*void apply3(function<void(int)> f, optional<int> i)
precondition{ bool(i) }
{
  f(*i);
}*

// no warning, at your own risk:
*void apply4(function<void(int)> f, optional<int> i)
{
  [[ satisfied(bool(i)) ]] f(*i);
}*

// safe (but tricky):
*void apply3(function<void(int)> f, optional<int> i)
{
  if (i == nullopt) { i = 0; }
  f(*i);
}*

"Safe" is not a guarantee that the precondition would hold (what if value 
is changed asynchronously?) but still it allows a certain degree of comfort.

The last example is problematic: how should the compiler know that 
contextual conversion to *bool *and the comparison against *nullopt *are 
'compatible'? This could be done with an invariant, but could as well be 
done with an axiom (as described in N2887<http://www.open-std.org/Jtc1/SC22/wg21/docs/papers/2009/n2887.pdf>). 
The latter appears a more universal choice.

for instance, if something is sorted, it is also partitioned:

*template <ForwardIterator IT, BinaryPredicate<ValueType<IT>> PR>*
*axiom being_sorted(IT b, IT e, PR p, ValueType<IT> v)*
*{*
*  is_sorted(b, e, p) => is_partitioned(b, e, [](auto x){ return p(x, v); 
});*
*}*

*template <Integal I>*
*axiom being_sorted(I i)*
*{*
*  is_positive(i) => is_nonnegative(i);*
*}*

This could be expressed as an invariant:

*class Integral {
  invariant {
    !is_positive(*this) || is_nonnegative(*this);
  }
};
*
But it looks more like a hack and puts some restrictions on the order of 
definitions: should *Integral *be defined first or function *is_positive*? 
Also, an axiom may be stated on two different types. In that case, it is 
not clear in the body of whose type  type the corresponding invariant could 
should be put:

*axiom (XVector v, XMatrix m)
{
  v * m <=> m * transposed(v); 
}*

You could arbitrarily pick one, but the relation applies to both classes.

It looks to me that axioms are a generalization (or a superset) or 
invariants. Perhaps they should be an integral part of contract 
programming. I wonder what others think.

Regards,
&rzej

-- 

--- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.



------=_Part_543_24950661.1370884959523
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hi Everyone,<br>I wanted to share, and run through the community, one thoug=
ht about contract programming features. Namely, that axioms (like those in =
concepts) are a superior alternative to invariants.<br><br>One of the goals=
 of contract programming support in C++ would be to=20
assist with static analysis. For instance, given the following=20
pre-/post-conditions for <b>std::optional</b><br><b><br></b><div style=3D"m=
argin-left: 40px;"><b>T&amp; optional&lt;T&gt;::operator*()<br>precondition=
{ bool(*this) };<br><br>T&amp; optional&lt;T&gt;::operator=3D(T&amp;&amp;)<=
br>postcondition{ bool(*this) }; </b><br><br></div>Compiler should be able =
to deduce the following:<br><br><div style=3D"margin-left: 40px;">// warnin=
g: precondition likely not met</div><div style=3D"margin-left: 40px;"><b>vo=
id apply(function&lt;void(int)&gt; f, optional&lt;int&gt; i)<br>{<br>&nbsp;=
 f(*i);<br>}<br></b><br>// safe (checked manually):<br><b>void apply1(funct=
ion&lt;void(int)&gt; f, optional&lt;int&gt; i)<br>{<br>&nbsp; if (i) { f(*i=
); }<br>}</b><br><br>// safe (postcondition matches the precondition):<br><=
b>void apply2(function&lt;void(int)&gt; f, optional&lt;int&gt; i)<br>{<br>&=
nbsp; i =3D 0;<br>&nbsp; f(*i);<br>}</b><br><br>// safe (preferable):<br><b=
>void apply3(function&lt;void(int)&gt; f, optional&lt;int&gt; i)<br>precond=
ition{ bool(i) }<br>{<br>&nbsp; f(*i);<br>}</b><br><br>// no warning, at yo=
ur own risk:<br><b>void apply4(function&lt;void(int)&gt; f, optional&lt;int=
&gt; i)<br>{<br>&nbsp; [[ satisfied(bool(i)) ]] f(*i);<br>}</b><br><br>// s=
afe (but tricky):<br><b>void apply3(function&lt;void(int)&gt; f, optional&l=
t;int&gt; i)<br>{<br>&nbsp; if (i =3D=3D nullopt) { i =3D 0; }<br>&nbsp; f(=
*i);<br>}</b><br><br></div>"Safe"
 is not a guarantee that the precondition would hold (what if value is=20
changed asynchronously?) but still it allows a certain degree of=20
comfort.<br><br>The last example is problematic: how should the compiler kn=
ow that contextual conversion to <b>bool </b>and the comparison against <b>=
nullopt </b>are 'compatible'? This could be done with an invariant, but cou=
ld as well be done with an axiom (as described in <a href=3D"http://www.ope=
n-std.org/Jtc1/SC22/wg21/docs/papers/2009/n2887.pdf">N2887</a>). The latter=
 appears a more universal choice.<br><br>for instance, if something is sort=
ed, it is also partitioned:<br><br><div style=3D"margin-left: 40px;"><b>tem=
plate &lt;ForwardIterator IT, BinaryPredicate&lt;ValueType&lt;IT&gt;&gt; PR=
&gt;</b><br><b>axiom being_sorted(IT b, IT e, PR p, ValueType&lt;IT&gt; v)<=
/b><br><b>{</b><br><b>&nbsp; is_sorted(b, e, p) =3D&gt; is_partitioned(b, e=
, [](auto x){ return p(x, v); });</b><br><b>}</b><br><br><b>template &lt;In=
tegal I&gt;</b><br><b>axiom being_sorted(I i)</b><br><b>{</b><br><b>&nbsp; =
is_positive(i) =3D&gt; is_nonnegative(i);</b><br><b>}</b><br><br></div>This=
 could be expressed as an invariant:<br><br><div style=3D"margin-left: 40px=
;"><b>class Integral {<br>&nbsp; invariant {<br>&nbsp; &nbsp; !is_positive(=
*this) || is_nonnegative(*this);<br>&nbsp; }<br>};<br></b><br></div>But it =
looks more like a hack and puts some restrictions on the order of definitio=
ns: should <b>Integral </b>be defined first or function <b>is_positive</b>?
 Also, an axiom may be stated on two different types. In that case, it=20
is not clear in the body of whose type&nbsp; type the corresponding invaria=
nt
 could should be put:<br><br><div style=3D"margin-left: 40px;"><b>axiom (XV=
ector v, XMatrix m)<br>{<br>&nbsp; v * m &lt;=3D&gt; m * transposed(v); <br=
>}</b><br><br></div>You could arbitrarily pick one, but the relation applie=
s to both classes.<br><br>It
 looks to me that axioms are a generalization (or a superset) or=20
invariants. Perhaps they should be an integral part of contract=20
programming. I wonder what others think.<br><br>Regards,<br>&amp;rzej<br>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_543_24950661.1370884959523--

.
