Received: from mx0.gmx.net (mx0.gmx.net [213.165.64.100]) by h1439878.stratoserver.net (8.14.2/8.14.2/Debian-2build1) with SMTP id o8M2dcQJ001433 for ; Wed, 22 Sep 2010 04:39:39 +0200 Received: (qmail 1958 invoked by alias); 22 Sep 2010 02:39:33 -0000 Delivered-To: GMX delivery to rainer.schoepf@gmx.net Received: (qmail invoked by alias); 22 Sep 2010 02:39:33 -0000 Received: from relay.uni-heidelberg.de (EHLO relay.uni-heidelberg.de) [129.206.100.212] by mx0.gmx.net (mx072) with SMTP; 22 Sep 2010 04:39:33 +0200 Received: from listserv.uni-heidelberg.de (listserv.uni-heidelberg.de [129.206.100.94]) by relay.uni-heidelberg.de (8.14.1/8.14.1) with ESMTP id o8M2b8ZC015694 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 22 Sep 2010 04:37:09 +0200 Received: from listserv.uni-heidelberg.de (localhost.localdomain [127.0.0.1]) by listserv.uni-heidelberg.de (8.13.1/8.13.1) with ESMTP id o8LM14CH010542; Wed, 22 Sep 2010 04:37:32 +0200 Received: by LISTSERV.UNI-HEIDELBERG.DE (LISTSERV-TCP/IP release 16.0) with spool id 435344 for LATEX-L@LISTSERV.UNI-HEIDELBERG.DE; Wed, 22 Sep 2010 04:37:32 +0200 Received: from relay2.uni-heidelberg.de (relay2.uni-heidelberg.de [129.206.210.211]) by listserv.uni-heidelberg.de (8.13.1/8.13.1) with ESMTP id o8M2bWpW001598 for ; Wed, 22 Sep 2010 04:37:32 +0200 Received: from mail-pw0-f49.google.com (mail-pw0-f49.google.com [209.85.160.49]) by relay2.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id o8M2cqkl002824 for ; Wed, 22 Sep 2010 04:38:56 +0200 Received: by pwj3 with SMTP id 3so69538pwj.22 for ; Tue, 21 Sep 2010 19:37:27 -0700 (PDT) Received: by 10.114.124.17 with SMTP id w17mr12909358wac.204.1285123047090; Tue, 21 Sep 2010 19:37:27 -0700 (PDT) Received: from [10.0.1.107] (114-30-106-154.ip.adam.com.au [114.30.106.154]) by mx.google.com with ESMTPS id o17sm16649310wal.21.2010.09.21.19.37.23 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 21 Sep 2010 19:37:25 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Apple Message framework v1081) References: <4C967C9B.5010706@gmx.de> <71ED7A5B-DE11-45D9-9785-95A1DC795080@gmail.com> <4C9724B4.3010301@residenset.net> <19607.26705.947540.499705@morse.mittelbach-online.de> <4C9840AB.4050805@gmx.de> <732A7500-5414-4818-87E3-33CB14463288@gmail.com> <4C98435A.1050507@gmx.de> <4C989ACB.5060000@morningstar2.co.uk> <353AB782-051D-400D-99B4-E3258AAB4F35@gmail.com> <4C99044E.8080303@morningstar2.co.uk> X-Mailer: Apple Mail (2.1081) X-Spam-Whitelist: Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by listserv.uni-heidelberg.de id o8M2bWpW001599 Message-ID: <5BF5993A-0BC8-4FC1-BD14-2E909DE5BE1F@gmail.com> Date: Wed, 22 Sep 2010 12:07:20 +0930 Reply-To: Mailing list for the LaTeX3 project Sender: Mailing list for the LaTeX3 project From: Will Robertson Subject: Re: boolean expressions in ExplSyntaxNames To: LATEX-L@listserv.uni-heidelberg.de In-Reply-To: <4C99044E.8080303@morningstar2.co.uk> Precedence: list List-Help: , List-Unsubscribe: List-Subscribe: List-Owner: List-Archive: X-GMX-Antispam: 0 (Mail was not recognized as spam); Detail=5D7Q89H36p6i75npGen84eVAEFK/syJmFuaL1OLtauwJ5R/kaZ9HAe8peGX1DeqJL7BW4 1X28hmBsSaikXt0ebYfUaHmtXkk7HChP+4IT8uNdVgNwDH5hrhnvoJ4U9x3qC9CkHcMikBVzVkV0 aKFtQ==V1; X-Resent-By: Forwarder X-Resent-For: rainer.schoepf@gmx.net X-Resent-To: rainer@rainer-schoepf.de Status: R X-Status: X-Keywords: X-UID: 6436 On 22/09/2010, at 4:45 AM, Joseph Wright wrote: > On 21/09/2010 14:05, Will Robertson wrote: >> I'm not willing to throw away the infix notation, > > I'd point out that we have an outstanding bug in the infix system with no obvious solution. For other readers, you'll find that > > \bool_if_p:n { ! (\c_true_bool) && \c_false_bool } > > gives the wrong result. I'd half-forgotten about this, oops. I've now studied the code and fixed up the problem in a rudimentary way (that's all I'm good for, really). For those who are interested I'll explain my analysis and solution below. This means I still want the infix notation to stick around, okay? :) But adding the optimised functional notation definitely seems like a good idea to me, as well. * * * The way the boolean infix notation works is all rather neat; a scanner looks ahead at the material to follow and branches accordingly, expanding everything as it goes with \romannumeral. This expanding-as-it-goes is where the problem started. When gathering boolean bits and combining them and expanding, everything works swimmingly with runs like ( 1 && 1 ) || ( 0 || 1 ) as each boolean subexpression can be collapsed linearly. E.g., the above essentially expands to (1) || ( 0 || 1) (0 || 1) (1) When there are negation symbols around, however, we have to be careful about how and when the logic reversal happens. The code said something like (don't follow this too closely) !(...) -> \expandafter \intexpr_if_even_p:n \number \expandafter \CLEANUP \number \expandafter \SCAN \expandafter \BOOL \romannumeral ... which all looks like quite a mess (and I possible transcribed it slightly incorrectly), but the gist of the matter is that the \romannumeral expansion ends up "running away" from the \ifodd, which doesn't get expanded until much later at an incorrect time. Hence explaining why !(TRUE) || FALSE was returning "true": after \romannumeral started inside the parentheses, it didn't stop until after the "|| FALSE" comparison, only after which was the negation applied. You could consider that the || had a higher precedence in this case; it was actually being interpreted as ! ((TRUE)||FALSE) * * * Well, my solution isn'y very elegant, but according to my tests everything is working correctly. Because of the runaway expansion in the design of the process, I couldn't see a way to limit the grouping of the negation, so I did the only other thing I could think of: invent a new grouping system that reverses its inner logic. (I tried adding in extra runaway expansion steps earlier in the process, but I didn't have a good handle on the system then and failed quickly. Perhaps there is a much simpler solution to the problem that what I've implemented!) Previously, |!(...)| expanded to |!| plus the regular code for grouping to process |(...)|, then the result was reversed. Now, the lookahead goes into a different code branch when it sees a group after a negation, and the fundamental logic inside this group is reversed. There is no "extra step" for performing the \intexpr_if_even_p:n reveral, so the logic now groups correctly. That's the idea, anyway. I've expanded the test suite for the boolean logic (it took me a few goes to get the different reversals correct) and I believe it's all working. But I really have to get some other work done today, so I'll have to stop there. Please let me know if you see any problems or areas for simplification in the code. Best regards, -- Will