00001 /* Part of the culibs project, <http://www.eideticdew.org/culibs/>. 00002 * Copyright (C) 2006--2007 Petter Urkedal <urkedal@nbi.dk> 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #ifndef CUEX_BINDING_H 00019 #define CUEX_BINDING_H 00020 00021 #include <cuex/fwd.h> 00022 #include <cuex/opn.h> 00023 #include <cuex/oprdefs.h> 00024 #include <cucon/fwd.h> 00025 00026 CU_BEGIN_DECLARATIONS 00027 /** \defgroup cuex_binding_h cuex/binding.h: Variable Binding using de Bruijn Indices 00028 ** @{\ingroup cuex_mod 00029 ** 00030 ** This provides variables, scoping constructs, and algorithms for expressions 00031 ** using de Bruijn indexes. This includes the built-in μ-recursion and 00032 ** λ-expressions. 00033 ** 00034 ** \see cuex_recursion_h 00035 **/ 00036 00037 /** An expression which is bound to the surrounding binding site after skipping 00038 ** \a l levels. That is, with \a l = 0 binds to the immediate surrounding 00039 ** binding site. */ 00040 CU_SINLINE cuex_t 00041 cuex_hole(int l) 00042 { 00043 cu_debug_assert(0 <= l && l < (1 << CUEX_OA_HOLE_INDEX_WIDTH)); 00044 return cuex_opn(CUEX_O0_HOLE | CUEX_OA_HOLE_INDEX(l)); 00045 } 00046 00047 /** True iff \a e is a de Bruijn variable. */ 00048 CU_SINLINE cu_bool_t 00049 cuex_is_hole(cuex_t e) 00050 { 00051 cuex_meta_t meta = cuex_meta(e); 00052 return cuex_meta_is_opr(meta) && cuex_og_hole_contains(meta); 00053 } 00054 00055 CU_SINLINE cuex_t cuex_mupath_null() { return cuex_null(); } 00056 00057 CU_SINLINE cuex_t 00058 cuex_mupath_pair(int level_diff, cuex_t head_seq, cuex_t tail_comp) 00059 { 00060 if (head_seq == cuex_mupath_null()) 00061 return tail_comp; 00062 else 00063 return cuex_opn(CUEX_O2_MUPATH | CUEX_OA_HOLE_INDEX(level_diff), 00064 head_seq, tail_comp); 00065 } 00066 00067 /** True iff \a opr binds a de Bruijn variable. A binding can only bind one 00068 ** such variable. */ 00069 CU_SINLINE cu_bool_t 00070 cuex_opr_is_binder(cuex_meta_t opr) 00071 { return cuex_og_binder_contains(opr); } 00072 00073 /** For all free de Bruijn variables in \a e, increment their index by \a 00074 ** j_diff. This prepares the subexpression \a e to be substituted down 00075 ** across \a j_diff bind-sites, or for negative, up across -\a j_diff 00076 ** bind-sites. */ 00077 cuex_t cuex_bfree_adjusted(cuex_t e, int j_diff); 00078 00079 /** Calls \a f(\e lr, \e lr_top) for each free de Bruijn variable in \a e, 00080 ** where \e lr is the de Bruijn index and \e lr_top is \a j_top plus the 00081 ** binding depth of the hole. \a j_top is level relative to \a e at and above 00082 ** which variables are considered to be free. */ 00083 void cuex_bfree_iter(cuex_t e, cu_clop(f, void, int, int), int j_top); 00084 00085 /** Transforms \a e by replacing each free de Bruijn variable with \a f (\e lr, 00086 ** \e lr_top), where \e lr is the de Bruijn index and \e lr_top is \a j_top 00087 ** plus the binding depth at which the variable occurs. \a j_top is the top 00088 ** level relative to \a e to consider free, typically 0. */ 00089 cuex_t cuex_bfree_tran(cuex_t e, cu_clop(f, cuex_t, int, int), int j_top); 00090 00091 cu_bool_t cuex_bfree_match(cu_clop(f, cu_bool_t, int, cuex_t, int), 00092 cuex_t p, cuex_t e, int j_top); 00093 00094 /** Inserts free variables of \a e into \a set, where \a j_top (usually 0) is 00095 ** considered to be the first unbound level. The index of the outermost 00096 ** variable is returned, or \c INT_MIN if there were no free variables. */ 00097 int cuex_bfree_into_uset(cuex_t e, int j_top, cucon_uset_t set); 00098 00099 /** Insert de Burijn indices of free variables of \a e in the range [\a j_top, 00100 ** \a j_clip) into \a set, and return the number of unique free variables in 00101 ** the range which were not already present in \a set. The indices inserted 00102 ** into \a set are relative to \a j_top. Pass \a j_top = \c 0 and \a j_clip = 00103 ** \c INT_MAX to consider all free variables of \a e. The bit-array is 00104 ** resized as needed to fit the largest index. */ 00105 int cuex_bfree_into_bitarray(cuex_t e, int j_top, int j_clip, 00106 cucon_bitarray_t set); 00107 00108 cuex_t cuex_reindex_by_int_stack(cuex_t e, int stack_top_level, 00109 int stack_span, cucon_stack_t stack); 00110 00111 /** The maximum number of binding sites, according to \ref 00112 ** cuex_og_binder_contains, which needs to be crossed to reach any leaf of \a 00113 ** e. */ 00114 int cuex_max_binding_depth(cuex_t e); 00115 00116 /** Returns the map {\e x ↦ \e S}, where \e x corresponds to a μ-bind 00117 ** subexpression of \a e, and \e S is a \ref cucon_uset of the de Bruijn 00118 ** indices of the free λ-variables of the body of the μ-bind. Each key \e x 00119 ** is a left-associated \ref CUEX_O2_METAPAIR list of all μ-bind expressions 00120 ** down to and including the one \e S applies to. 00121 ** 00122 ** As an optimisation, a known result of \a cuex_max_binding_depth may be 00123 ** passed for \a max_binding_depth, otherwise pass -1. */ 00124 cucon_pmap_t cuex_unfolded_fv_sets(cuex_t e, int max_binding_depth); 00125 00126 #define CUEX_BI_SIFI_FLAG_PRUNE 1 00127 00128 void cuex_bi_sifi_indexing_accu(cuex_t e, unsigned int flags, 00129 cucon_pmap_t accu); 00130 00131 cucon_pmap_t cuex_bi_sifi_indexing(cuex_t e, unsigned int flags); 00132 00133 /** @} */ 00134 CU_END_DECLARATIONS 00135 00136 #endif