00001 /* 00002 * Q.h - support for ForAll, ThereExists, Count and Sum (i.e. quantifiers). 00003 * 00004 * Portability: this file uses the GNU C Statement Expression extension and 00005 * so requires GCC/C++ with extensions enabled (this is checked by the 00006 * header file). 00007 * 00008 * Copyright (c) 1997 Phil Maker 00009 * All rights reserved. 00010 * 00011 * Redistribution and use in source and binary forms, with or without 00012 * modification, are permitted provided that the following conditions 00013 * are met: 00014 * 1. Redistributions of source code must retain the above copyright 00015 * notice, this list of conditions and the following disclaimer. 00016 * 2. Redistributions in binary form must reproduce the above copyright 00017 * notice, this list of conditions and the following disclaimer in the 00018 * documentation and/or other materials provided with the distribution. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 00021 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00022 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00023 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 00024 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00025 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00026 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00027 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00028 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00029 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00030 * SUCH DAMAGE. 00031 * 00032 * Id: Q.h,v 1.1.1.1 1997/11/23 11:45:50 pjm Exp 00033 */ 00034 00035 00036 #ifndef _Q_h_ 00037 #define _Q_h_ 1 00038 00039 #ifdef __cplusplus 00040 extern "C" { 00041 #endif 00042 00043 #ifndef WITHOUT_NANA 00044 00045 #ifndef __GNUC__ /* not compiling with GCC/G++ extensions */ 00046 error 00047 This file requires the GNU C/C++ "statement expression" extension; 00048 so use GCC/G++ with extensions enabled. If you have not got GCC then 00049 misery follows though we may be able to do something about it 00050 in the future. 00051 #endif 00052 00053 /* 00054 * A(i,c,n,a) - true iff a is true for all values generated by for(i;c;n) 00055 * 00056 * Note: local variables can be introduced in this statement even in C. 00057 */ 00058 00059 #define A(i,c,n,a) /* ForAll */ \ 00060 ({ \ 00061 int _A_result = 1; \ 00062 i; \ 00063 while(c) { \ 00064 if(!(a)) { \ 00065 _A_result = 0; \ 00066 break; \ 00067 } \ 00068 n; \ 00069 } \ 00070 _A_result; \ 00071 }) 00072 00073 /* 00074 * E(i,c,n,a) - true iff exists any true a for values generated by for(i;c;n) 00075 */ 00076 00077 #define E(i,c,n,a) /* Exists */ \ 00078 ({ \ 00079 int _E_result = 0; \ 00080 i; \ 00081 while(c) { \ 00082 if(a) { \ 00083 _E_result = 1; \ 00084 break; \ 00085 } \ 00086 n; \ 00087 } \ 00088 _E_result; \ 00089 }) 00090 00091 /* 00092 * C(i,c,n,a) - count the number of times a is true over the values 00093 * generated by for(i;c;n) 00094 */ 00095 00096 #define C(i,c,n,a) /* Count */ \ 00097 ({ \ 00098 long _C_result = 0; \ 00099 i; \ 00100 while(c) { \ 00101 if(a) { \ 00102 _C_result++; \ 00103 } \ 00104 n; \ 00105 } \ 00106 _C_result; \ 00107 }) 00108 00109 /* 00110 * E1(i,c,n,a) - exists a single value generated by for(i;c;n) 00111 * suchthat i is true. 00112 */ 00113 00114 #define E1(i,c,n,a) (C(i,c,n,a) == 1) /* There Exists 1 */ 00115 00116 /* 00117 * S(i,c,n,v) - sum of v over the values generated by for(i;c;n) 00118 */ 00119 00120 #define S(i,c,n,v) \ 00121 ({ \ 00122 i; \ 00123 typeof(v) _S_result = 0; \ 00124 while(c) { \ 00125 _S_result += (v); \ 00126 n; \ 00127 } \ 00128 _S_result; \ 00129 }) 00130 00131 /* 00132 * P(i,c,n,v) - product of v over the values generated by for(i;c;n) 00133 */ 00134 00135 #define P(i,c,n,v) \ 00136 ({ \ 00137 i; \ 00138 typeof(v) _P_result = 1; \ 00139 while(c) { \ 00140 _P_result *= (v); \ 00141 n; \ 00142 } \ 00143 _P_result; \ 00144 }) 00145 00146 #else /* defined(WITHOUT_NANA) */ 00147 00148 /* 00149 * we don't produce any empty stubs for Q.h when compiling without nana 00150 * since calls to A(...), etc should only occur in stubbed out code such 00151 * as I(...). 00152 */ 00153 00154 #endif /* !defined(WITHOUT_NANA) */ 00155 #ifdef __cplusplus 00156 } 00157 #endif 00158 00159 #endif /* _Q_h_ */ 00160
1.3.4