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 q17CGulc027920 for ; Tue, 7 Feb 2012 13:16:58 +0100 Received: (qmail 21155 invoked by alias); 7 Feb 2012 12:16:51 -0000 Delivered-To: GMX delivery to rainer.schoepf@gmx.net Received: (qmail invoked by alias); 07 Feb 2012 12:16:51 -0000 Received: from relay2.uni-heidelberg.de (EHLO relay2.uni-heidelberg.de) [129.206.210.211] by mx0.gmx.net (mx040) with SMTP; 07 Feb 2012 13:16:51 +0100 Received: from listserv.uni-heidelberg.de (listserv.uni-heidelberg.de [129.206.100.94]) by relay2.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id q17CEDjV014202 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 7 Feb 2012 13:14:14 +0100 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 q17Bvb9i001708; Tue, 7 Feb 2012 13:14:13 +0100 Received: by LISTSERV.UNI-HEIDELBERG.DE (LISTSERV-TCP/IP release 16.0) with spool id 1942020 for LATEX-L@LISTSERV.UNI-HEIDELBERG.DE; Tue, 7 Feb 2012 13:14:13 +0100 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 q17CECnN014962 for ; Tue, 7 Feb 2012 13:14:12 +0100 Received: from neptune.ucc.ie (neptune.ucc.ie [143.239.153.183]) by relay2.uni-heidelberg.de (8.13.8/8.13.8) with ESMTP id q17CDnvU013809 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 7 Feb 2012 13:13:55 +0100 Received: from csmvddesktop (csmvddesktop.ucc.ie [143.239.74.97]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) (Authenticated sender: dongen) by neptune.ucc.ie (Postfix) with ESMTPSA id E221C20064 for ; Tue, 7 Feb 2012 12:14:11 +0000 (GMT) References: <20120202131844.GA16372@csmvddesktop> <20120202133153.GA16604@csmvddesktop> <20120203151218.GA30208@csmvddesktop> <4F2BFFA6.1020306@morningstar2.co.uk> <20120203155926.GA30436@csmvddesktop> <20120205160826.GA6939@csmvddesktop> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="8t9RHnE3ZwKMSgU+" Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Message-ID: <20120207121838.GA29522@csmvddesktop> Date: Tue, 7 Feb 2012 12:18:38 +0000 Reply-To: Mailing list for the LaTeX3 project Sender: Mailing list for the LaTeX3 project From: dongen Subject: Re: Mapping Functions Versions for All and Some To: LATEX-L@listserv.uni-heidelberg.de In-Reply-To: Precedence: list List-Help: , List-Unsubscribe: List-Subscribe: List-Owner: List-Archive: X-GMX-Antispam: 0 (eXpurgate); Detail=5D7Q89H36p7zYQev1Bv5lawyulDRL8ctGSPpXvYw1nbVMeJ98FkLsAVXycSQpAD1gchUk HnEYegGVXE8rOdmuBDK/9WDxdlrfHIuS4VtrNyJb49S3CnLKnniZ0txxcbUISd7ggoac1cNwNpiI rnwOLfxyzjzaCUYBzUkdK4nbZ3khuxm2mMPiDxmZ6Rov5YwxG/YPIH4v/c=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: 7031 --8t9RHnE3ZwKMSgU+ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline * Bruno Le Floch [2012-02-05 13:01:41 -0500]: Dear Bruno, I finaly solved the problem. It was related to substitution issues (as you already pointed out correcty). I have one question regarding your suggestion: : \DeclareDocumentCommand{\f}{om} : { : : \IfValue{#1} : { \tl_set:NV #1 \l_recurrence_result_int } : { \int_use:N \l_recurrence_result_int } : } I don't see how this can work. (Maybe it works for fibonacci-like recurrences.) For example, the computation only uses one counter, so it seems to me that it cannot benefit from recurrences like g[ 0 ] = 0, g[ 1 ] = 1, g[ 2 ] = 2, g[ i ] = g[ i - 1 ] + g[ i - 2 ] + g[ i - 3 ] Am I missing something? I'm attaching the sources. The implementation still doesn't work properly because guard expressions aren't parsed correctly. I'll fix this first and then reimplement the module for more than one index (and perhaps multiple functions). Thanks again for your help. I've learnt a lot. Regards, Marc --8t9RHnE3ZwKMSgU+ Content-Type: text/x-tex; charset=us-ascii Content-Disposition: attachment; filename="recurrence.sty" \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{recurrence}[2012/02/02 Recurrence Equation Support] %\usepackage{tikz} \usepackage{xparse} \usepackage{expl3} \usepackage{l3regex} \usepackage{l3int} \ExplSyntaxOn \tl_new:N \l_recurrence_bin_tl \tl_new:N \l_recurrence_temp_seq \tl_new:N \l_recurrence_name_tl \tl_new:N \l_recurrence_index_tl \tl_new:N \l_recurrence_rhs_tl \tl_new:N \l_recurrence_guard_tl \int_new:N \l_recurrence_case_count_int \int_new:N \l_recurrence_current_case_count_int % FOLLOWING NOT USED \regex_const:Nn \c_recurrence_true_regex { true } \regex_const:Nn \c_recurrence_sqbr_regex { \[([^\]]*)\] } \regex_const:Nn \c_recurrence_and_regex { and } \regex_const:Nn \c_recurrence_or_regex { or } \regex_const:Nn \c_recurrence_even_regex { \b even \b } \regex_const:Nn \c_recurrence_odd_regex { \b odd \b } \regex_const:Nn \c_recurrence_integer_regex { ^[-+]*[0-9]+$ } \tl_const:Nn \c_recurrence_prefix_tl { recurrence } \cs_new_protected_nopar:Npn \recurrence_error:nn #1#2{ \msg_interrupt:xxx {Fatal~recurrence~module~error.} {#1} {#2} } \cs_new_protected_nopar:Npn \recurrence_syntax_error:n #1 { \recurrence_error:nn { Syntax~error.~You~cannot~write:~#1. Expressions~should~be~of~the~form:~ "function[~index~or~constant~]~=~expression"~or~ "function[~index~or~constant~]~=~expression~|~guard~expression". } { For~example,~you~could~define~the~Fibonacci~numbers~as~follows: \\NewRecDef\{~f[0]~=~1,~f[1]~=~1,~f[i]~=~f[i-1]~+~f[i-2]~\|~i~>~1~\}.~ another~possibility~is~ \\NewRecDef\{~f[i]~=~1~\|~0~<=~i~\&\&~i~<=~1,~f[1]~=~1,~f[i]~=~f[i-1]~+~f[i-2]~\|~i~>~1~\}. } } \cs_new_protected_nopar:Npn \recurrence_undefined_error:nn #1#2 { \recurrence_error:nn { #1[~#2~]~is undefined. } { This~probably~means~that~your~base~case~ definitions~aren't~defined~properly. } } % #1 is expression \cs_new_protected_nopar:Npn \recurrence_is_integer:nTF #1{ \regex_match:NnTF \c_recurrence_integer_regex {#1} } \cs_generate_variant:Nn \recurrence_is_integer:nTF { V } \cs_new_nopar:Npn \recurrence_case_name:nn #1#2{ \tl_use:N \c_recurrence_prefix_tl _ #1 _ #2:n } % #1 is integer variable \cs_new_nopar:Npn \recurrence_case_name:n #1{ \recurrence_case_name:nn \l_recurrence_name_tl {\int_eval:n #1} } % #1 is index % #2 is rhs \cs_new_nopar:Npn \recurrence_define_constant:xx #1#2{% \int_set_eq:NN \l_recurrence_current_case_count_int \l_recurrence_case_count_int \int_incr:N \l_recurrence_case_count_int \cs_new_nopar:cpx {\recurrence_case_name:n \l_recurrence_current_case_count_int} ##1{ \exp_not:N \int_compare:nTF {##1=#1} {#2} {\exp_not:c {\recurrence_case_name:n \l_recurrence_case_count_int}{##1}} } } % #1 is guard tl % #2 is rhs tl \cs_new_nopar:Npn \recurrence_case_definition:xx #1#2{ \int_set_eq:NN \l_recurrence_current_case_count_int \l_recurrence_case_count_int \int_incr:N \l_recurrence_case_count_int \cs_new_nopar:cpx {\recurrence_case_name:n \l_recurrence_current_case_count_int} ##1{ \exp_not:N \bool_if:nTF {#1} {#2} {\exp_not:c {\recurrence_case_name:n \l_recurrence_case_count_int} {##1}} } } % #1 is name tl % #2 is index tl \cs_new_nopar:Npn \recurrence_case_definition:NN #1#2{ \recurrence_sanitise:VVN #1 #2 \l_recurrence_rhs_tl \recurrence_sanitise:VVN #1 #2 \l_recurrence_guard_tl \regex_replace_all:NnN \c_recurrence_true_regex {\c{int_compare_p:n} \cB\{ 1 = 1 \cE\}} \l_recurrence_guard_tl \recurrence_case_definition:xx \l_recurrence_guard_tl \l_recurrence_rhs_tl } % #1 is name % #2 is index % #3 is tl list \cs_new_nopar:Npn \recurrence_sanitise:nnN #1#2#3{ \regex_replace_all:nnN {#2} {\cP\# 1} #3 \regex_replace_all:NnN \c_recurrence_sqbr_regex {\cB\{\1\cE\}} #3 \regex_replace_all:NnN \c_recurrence_or_regex {||} #3 \regex_replace_all:NnN \c_recurrence_and_regex {&&} #3 \regex_replace_all:NnN \c_recurrence_even_regex {\c{exp_not:N} \c{int_if_even_p:n}} #3 \regex_replace_all:NnN \c_recurrence_odd_regex {\c{exp_not:N} \c{int_if_odd_p:n}} #3 \regex_replace_all:nnN {\b\u{l_recurrence_name_tl}\b} {\c{exp_not:N} \c{\u{l_recurrence_name_tl}:n}} #3 } \cs_generate_variant:Nn \recurrence_sanitise:nnN {VV} \cs_new_nopar:Npn \recurrence_error_definition:{ \int_set_eq:NN \l_recurrence_current_case_count_int \l_recurrence_case_count_int \cs_new:cpx {\recurrence_case_name:n \l_recurrence_current_case_count_int}##1{ 0 \exp_not:N \recurrence_undefined_error:nn {\tl_use:N \l_recurrence_name_tl} {##1} } } \cs_new_nopar:Npn \recurrence_wrapper_definitions:{ \cs_new_nopar:cpx { \l_recurrence_name_tl } ##1{% \exp_not:N \int_eval:n {\exp_not:c { \l_recurrence_name_tl :n } {##1}} } \cs_new_nopar:cpx { \l_recurrence_name_tl :n } ##1{% \exp_not:N \exp_args:Nf \exp_not:c { \recurrence_case_name:n 0 } { \exp_not:N \int_eval:n {##1} } } } \cs_new_nopar:Npn \recurrence_rec_def:n #1{ \group_begin: \clist_set:Nn \recurrence_csv_list {#1} \clist_map_inline:Nn \recurrence_csv_list { \regex_extract_once:nnNTF { ^(\w+)\[(\w+)\]\=(.+?)\|([^\|]+|\|\|)+\|(.+) } {##1|true||} \l_recurrence_temp_seq { % at this stage, \l_recurrence_temp_seq has 6 items, % 0th: a[i]= expression | guard | guard option \seq_pop:NN \l_recurrence_temp_seq \l_recurrence_bin_tl \seq_pop:NN \l_recurrence_temp_seq \l_recurrence_name_tl \seq_pop:NN \l_recurrence_temp_seq \l_recurrence_index_tl \seq_pop:NN \l_recurrence_temp_seq \l_recurrence_rhs_tl \seq_pop:NN \l_recurrence_temp_seq \l_recurrence_guard_tl \recurrence_is_integer:VTF \l_recurrence_index_tl {\recurrence_define_constant:xx \l_recurrence_index_tl \l_recurrence_rhs_tl} {\recurrence_case_definition:NN \l_recurrence_name_tl \l_recurrence_index_tl} } { \recurrence_syntax_error:n {##1} } } \recurrence_error_definition: \recurrence_wrapper_definitions: \group_end: } \DeclareDocumentCommand\NewRecDef{ m }{ \recurrence_rec_def:n {#1} } \ExplSyntaxOff --8t9RHnE3ZwKMSgU+ Content-Type: text/x-tex; charset=us-ascii Content-Disposition: attachment; filename="recurrence.tex" \documentclass[12pt]{article} \usepackage[paper=a4paper,landscape]{geometry} \usepackage{recurrence} \usepackage{booktabs} \ExplSyntaxOn \int_new:N \l_int \newcommand\MyRecurrence[3]{% \NewRecDef{#3} \int_set:Nn \l_int {0} \begin{tabular}{lr} \toprule $x$ & \multicolumn{1}{r}{$#1( x )$} \\\midrule \int_while_do:nNnn {\l_int} < {21}{% \int_use:N \l_int & #2{\l_int} \global\int_incr:N \l_int \\ } \bottomrule \end{tabular} } \ExplSyntaxOff \begin{document} \MyRecurrence{f}{\f}{f[0]=1,f[1]=1,f[i]=f[i-1]+f[i-2]} \MyRecurrence{g}{\g}{g[0]=0,g[1]=1,g[2]=2,g[i]=g[i-1]+g[i-2]+g[i-3]} % %\begin{tt} %\begin{tabular}{ll} % f & \meaning\f %\\ f:n & \expandafter\meaning\csname f:n\endcsname %\\ recurrence\_f\_0:n & \expandafter\meaning\csname recurrence_f_0:n\endcsname %\\ recurrence\_f\_1:n & \expandafter\meaning\csname recurrence_f_1:n\endcsname %\\ recurrence\_f\_2:n & \expandafter\meaning\csname recurrence_f_2:n\endcsname %\\ recurrence\_f\_3:n & \expandafter\meaning\csname recurrence_f_3:n\endcsname %\end{tabular} %\end{tt} %\cs_set_nopar:cpn {recurrence_f_2:n} #1 { %\bool_if:nTF { \c_true_bool }{\f:n{#1-1}+\f:n{#1-2}}{\recurrence_f_3:n {#1}} %} % %\f{2}, % \end{document} --8t9RHnE3ZwKMSgU+--