/* translation of file "pat.k" */
/* generated by:
 *  @(#)$Author$
 */
#define KC_FUNCTIONS_pat_

#include <stdlib.h>
#include "k.h"
#include "pat.h"
namespace kc { }
using namespace kc;
/* included stuff */
//
// The Termprocessor Kimwitu++
//
// Copyright (C) 1991 University of Twente, Dept TIOS.
// Copyright (C) 1998-2003 Humboldt-University of Berlin, Institute of Informatics
// All rights reserved.
//
// Kimwitu++ is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Kimwitu++ is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kimwitu++; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

static char pat_kAccesSid[] = "@(#)$Id$";

#include "util.h"
#include "gutil.h" /* for f_operatorofpatternrepresentation() */

bindingidmarks Thebindingidmarks = 0;

/* end included stuff */


namespace kc {

#ifndef KC_TRACE_PROVIDED
#define KC_TRACE_PROVIDED(COND,FILE,LINE,NODE) COND
#endif

static  patternrepresentation t_syn_patternchain (patternchain a_patternchain, path a_path, int branch);
static  patternrepresentation syn_outmostpattern (outmostpattern a_outmostpattern, path a_path);
static  patternrepresentation syn_pattern (pattern a_pattern, path a_path);
static  patternrepresentation syn_patterns (patterns a_patterns, path a_path);
static  patternrepresentation t_syn_patterns (patterns a_patterns, path a_path, int branch);
static  patternrepresentation add_predicates (patternrepresentation a_patternrep);
static  patternrepresentation add_predicate (elem_patternrepresentation a_patternrep_elem, patternrepresentation a_patternrep);
static  patternrepresentation t_make_predicates (ID a_id, paths a_paths, patternrepresentation a_subpattern, patternrepresentation a_patternrep, bool left_linear);
static  patternrepresentation make_predicates (elem_patternrepresentation a_patternrep_elem, patternrepresentation a_patternrep);
static  bool test_matching_subpatterns (patternrepresentation newp, patternrepresentation oldp);
static  patternrepresentation f_get_predicates (patternrepresentation a_patternrep);
static  patternrepresentation f_get_bindings (patternrepresentation a_patternrep);
static  patternrepresentation f_do_get_bindings (patternrepresentation a_patternrep);
static  rewriterulesinfo insertin_rewriterulesinfo (rewriteruleinfo new_rule, rewriterulesinfo old_rules);
static  bool lt_rewriteruleinfo (rewriteruleinfo a_rwruleinfo1, rewriteruleinfo a_rwruleinfo2);
static  unparsedeclsinfo insertin_unparsedeclsinfo (unparsedeclinfo new_decl, unparsedeclsinfo old_decls);
static  bool lt_unparsedeclinfo (unparsedeclinfo a_unparsedeclinfo1, unparsedeclinfo a_unparsedeclinfo2);
static  bool lt_patternrepresentation (patternrepresentation pr1, patternrepresentation pr2);
static  tribool equal_elem_patternrepresentation (elem_patternrepresentation a_patternrep_elem1, elem_patternrepresentation a_patternrep_elem2);
static  tribool equal_path (path a_path1, path a_path2);
static  tribool equal_paths (paths a_paths1, paths a_paths2);
patternrepresentations syn_patternchains(patternchains a_patternchains)
{{
	patternchains kc_selvar_0_1 = phylum_cast<patternchains>(a_patternchains);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatternchains)) {
	    const patternchain a_patternchain = (kc_selvar_0_1)->patternchain_1;
	    const patternchains r_patternchains = (kc_selvar_0_1)->patternchains_1;

	    return Conspatternrepresentations(
		syn_patternchain( a_patternchain, Nilpath() ),
		syn_patternchains(  r_patternchains )
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternchains)) {

	    return Nilpatternrepresentations();

	} else
	{ kc_no_default_in_with( "syn_patternchains", __LINE__, __FILE__ );
	    return static_cast<patternrepresentations>(0); }
    }

}

patternrepresentation syn_patternchain(patternchain a_patternchain, path a_path)
{{
	patternchain kc_selvar_0_1 = phylum_cast<patternchain>(a_patternchain);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatternchain)) {

	    return t_syn_patternchain( a_patternchain, a_path, a_patternchain->length());

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternchain)) {

	    return Nilpatternrepresentation();

	} else
	{ kc_no_default_in_with( "syn_patternchain", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

static  patternrepresentation t_syn_patternchain(patternchain a_patternchain, path a_path, int branch)
{{
	patternchain kc_selvar_0_1 = phylum_cast<patternchain>(a_patternchain);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatternchain)) {
	    const patternchainitem a_patternchainitem = (kc_selvar_0_1)->patternchainitem_1;
	    const patternchain r_patternchain = (kc_selvar_0_1)->patternchain_1;

	    return concat( t_syn_patternchain(  r_patternchain, a_path , branch-1 ), syn_patternchainitem( a_patternchainitem, Conspath( mkinteger(branch), a_path ) ) );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternchain)) {

	    return Nilpatternrepresentation();

	} else
	{ kc_no_default_in_with( "t_syn_patternchain", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

patternrepresentation syn_patternchainitem(patternchainitem a_patternchainitem, path a_path)
{{
	patternchainitem kc_selvar_0_1 = phylum_cast<patternchainitem>(a_patternchainitem);
	if ((kc_selvar_0_1->prod_sel() == sel_PatternchainitemDollarid)) {
	    const ID id = phylum_cast<const impl_patternchainitem_PatternchainitemDollarid*>(kc_selvar_0_1)->ID_1;

	    elem_patternrepresentation tmp = PRBinding( a_path, id );
	    tmp->type = a_patternchainitem->type;
	    return Conspatternrepresentation(
		tmp,
		Nilpatternrepresentation()
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PatternchainitemGroup)) {

	    v_report( NonFatal(  FileLine( a_patternchainitem->file, a_patternchainitem->line ),
		    Problem1S( "Internal Error: PatternchainitemGroup was not handled correctly" )));
	    return Nilpatternrepresentation();

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PatternchainitemOutmost)) {
	    const outmostpattern a_outmostpattern = phylum_cast<const impl_patternchainitem_PatternchainitemOutmost*>(kc_selvar_0_1)->outmostpattern_1;

	    return syn_outmostpattern( a_outmostpattern, a_path );

	} else
	{ kc_no_default_in_with( "syn_patternchainitem", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

patternrepresentations syn_outmostpatterns(outmostpatterns a_outmostpatterns)
{{
	outmostpatterns kc_selvar_0_1 = phylum_cast<outmostpatterns>(a_outmostpatterns);
	if ((kc_selvar_0_1->prod_sel() == sel_Consoutmostpatterns)) {
	    const outmostpattern a_outmostpattern = (kc_selvar_0_1)->outmostpattern_1;
	    const outmostpatterns r_outmostpatterns = (kc_selvar_0_1)->outmostpatterns_1;

	    return Conspatternrepresentations(
		syn_outmostpattern( a_outmostpattern, Nilpath() ),
		syn_outmostpatterns(  r_outmostpatterns )
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Niloutmostpatterns)) {

	    return Nilpatternrepresentations();

	} else
	{ kc_no_default_in_with( "syn_outmostpatterns", __LINE__, __FILE__ );
	    return static_cast<patternrepresentations>(0); }
    }

}

void clone_TypeFileLine(elem_patternrepresentation tmp1, outmostpattern a_outmostpattern)
{
    tmp1->type = a_outmostpattern->type;
    tmp1->file = a_outmostpattern->file;
    tmp1->line = a_outmostpattern->line;

}

static  patternrepresentation syn_outmostpattern(outmostpattern a_outmostpattern, path a_path)
{
    patternrepresentation result;
    Cexpression condition;
    {
	outmostpattern kc_selvar_0_1 = phylum_cast<outmostpattern>(a_outmostpattern);
	if ((kc_selvar_0_1->prod_sel() == sel_OPWildcard)) {
	    const Cexpression cond = phylum_cast<const impl_outmostpattern_OPWildcard*>(kc_selvar_0_1)->Cexpression_1;

	    condition = cond;
	    elem_patternrepresentation tmp1 = PRWildcard( a_path );
	    clone_TypeFileLine(tmp1, a_outmostpattern);
	    result = Conspatternrepresentation(
		tmp1,
		Nilpatternrepresentation()
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_OPDefault)) {
	    const Cexpression cond = phylum_cast<const impl_outmostpattern_OPDefault*>(kc_selvar_0_1)->Cexpression_1;

	    condition = cond;
	    elem_patternrepresentation tmp1 = PRDefault();
	    clone_TypeFileLine(tmp1, a_outmostpattern);
	    result = Conspatternrepresentation(
		tmp1,
		Nilpatternrepresentation()
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_OPNonLeafVariable)) {
	    const ID id = phylum_cast<const impl_outmostpattern_OPNonLeafVariable*>(kc_selvar_0_1)->ID_1;
	    const outmostpattern r_pattern = phylum_cast<const impl_outmostpattern_OPNonLeafVariable*>(kc_selvar_0_1)->outmostpattern_1;

	    condition = NilCexpression();


	    elem_patternrepresentation tmp1 = PRNonLeafBinding( a_path, id, syn_outmostpattern( r_pattern, Nilpath()) );
	    a_path->id = f_phylumofpatternID(id);
	    clone_TypeFileLine(tmp1, a_outmostpattern);
	    result = Conspatternrepresentation(
		tmp1,
		syn_outmostpattern( r_pattern, a_path )
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_OPOperator)) {
	    const ID id = phylum_cast<const impl_outmostpattern_OPOperator*>(kc_selvar_0_1)->ID_1;
	    const patterns r_patterns = phylum_cast<const impl_outmostpattern_OPOperator*>(kc_selvar_0_1)->patterns_1;
	    const Cexpression cond = phylum_cast<const impl_outmostpattern_OPOperator*>(kc_selvar_0_1)->Cexpression_1;

	    condition = cond;
	    elem_patternrepresentation tmp1 = PROperPredicate( Conspath( mkinteger(0), a_path ), id );
	    clone_TypeFileLine(tmp1, a_outmostpattern);
	    a_path->op = id;
	    result = Conspatternrepresentation(
		tmp1,
		syn_patterns( r_patterns, a_path )
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_OPOperatorWildcard)) {
	    const ID id = phylum_cast<const impl_outmostpattern_OPOperatorWildcard*>(kc_selvar_0_1)->ID_1;
	    const Cexpression cond = phylum_cast<const impl_outmostpattern_OPOperatorWildcard*>(kc_selvar_0_1)->Cexpression_1;

	    condition = cond;

	    {
		ID kc_selvar_1_1 = phylum_cast<ID>( id );
		if ((kc_selvar_1_1->prod_sel() == sel_Id)) {
		    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_1_1)->uniqID_1;

		    {
			IDtype kc_selvar_2_1 = phylum_cast<IDtype>( uid->type );
			if ((kc_selvar_2_1->prod_sel() == sel_ITUnknown)) {

			    elem_patternrepresentation tmp1 = PRBinding( a_path, id );
			    clone_TypeFileLine(tmp1, a_outmostpattern);
			    result = Conspatternrepresentation(
				tmp1,
				Nilpatternrepresentation()
			    );

			} else
			    if ((kc_selvar_2_1->prod_sel() == sel_ITPatternVariable)) {

			    elem_patternrepresentation tmp1 = PRBinding( a_path, id );
			    clone_TypeFileLine(tmp1, a_outmostpattern);
			    result = Conspatternrepresentation(
				tmp1,
				Nilpatternrepresentation()
			    );

			} else
			{

			    elem_patternrepresentation tmp1 = PROperPredicate( Conspath( mkinteger(0), a_path ), id );
			    clone_TypeFileLine(tmp1, a_outmostpattern);
			    a_path->op = id;
			    result = Conspatternrepresentation(
				tmp1,
				Nilpatternrepresentation()
			    );

			}
		    }

		} else
		{ kc_no_default_in_with( "syn_outmostpattern", __LINE__, __FILE__ );
		    return static_cast<patternrepresentation>(0); }
	    }

	} else
	{ kc_no_default_in_with( "syn_outmostpattern", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }
    if (!condition->is_nil())
    result->append(PRUserPredicate(condition));
    return result;

}

static  patternrepresentation syn_pattern(pattern a_pattern, path a_path)
{{
	pattern kc_selvar_0_1 = phylum_cast<pattern>(a_pattern);
	if ((kc_selvar_0_1->prod_sel() == sel_PIntLiteral)) {
	    const INT i = phylum_cast<const impl_pattern_PIntLiteral*>(kc_selvar_0_1)->INT_1;

	    return Conspatternrepresentation(
		PRIntLiteral( a_path, i ),
		Nilpatternrepresentation()
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PStringLiteral)) {
	    const CexpressionDQ cexprdq = phylum_cast<const impl_pattern_PStringLiteral*>(kc_selvar_0_1)->CexpressionDQ_1;

	    return Conspatternrepresentation(
		PRStringLiteral( a_path, cexprdq ),
		Nilpatternrepresentation()
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PWildcard)) {



	    return Nilpatternrepresentation();

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PNonLeafVariable)) {
	    const ID id = phylum_cast<const impl_pattern_PNonLeafVariable*>(kc_selvar_0_1)->ID_1;
	    const pattern r_pattern = phylum_cast<const impl_pattern_PNonLeafVariable*>(kc_selvar_0_1)->pattern_1;

	    return Conspatternrepresentation(
		PRNonLeafBinding( a_path, id, syn_pattern( r_pattern, Nilpath()) ),
		syn_pattern( r_pattern, a_path )
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_POperator)) {
	    const ID id = phylum_cast<const impl_pattern_POperator*>(kc_selvar_0_1)->ID_1;
	    const patterns r_patterns = phylum_cast<const impl_pattern_POperator*>(kc_selvar_0_1)->patterns_1;

	    a_path->op = id;
	    return Conspatternrepresentation(
		PROperPredicate( Conspath( mkinteger(0), a_path ), id ),
		syn_patterns( r_patterns, a_path )
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PVariable)) {
	    const ID id = phylum_cast<const impl_pattern_PVariable*>(kc_selvar_0_1)->ID_1;

	    return Conspatternrepresentation(
		PRBinding( a_path, id ),
		Nilpatternrepresentation()
	    );

	} else
	{ kc_no_default_in_with( "syn_pattern", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

static  patternrepresentation syn_patterns(patterns a_patterns, path a_path)
{{
	patterns kc_selvar_0_1 = phylum_cast<patterns>(a_patterns);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatterns)) {

	    return t_syn_patterns(  a_patterns, a_path , a_patterns->length( ) );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilpatterns)) {

	    return Nilpatternrepresentation();

	} else
	{ kc_no_default_in_with( "syn_patterns", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

static  patternrepresentation t_syn_patterns(patterns a_patterns, path a_path, int branch)
{{
	patterns kc_selvar_0_1 = phylum_cast<patterns>(a_patterns);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatterns)) {
	    const pattern a_pattern = (kc_selvar_0_1)->pattern_1;
	    const patterns r_patterns = (kc_selvar_0_1)->patterns_1;

	    return concat( t_syn_patterns(  r_patterns, a_path , branch-1 ), syn_pattern( a_pattern, Conspath( mkinteger(branch), a_path ) ) );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilpatterns)) {

	    return Nilpatternrepresentation();

	} else
	{ kc_no_default_in_with( "t_syn_patterns", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

bool f_bindingidmarked(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    return BindingIdMark( uid )->marked;

	} else
	{ kc_no_default_in_with( "f_bindingidmarked", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

void v_markbindingid(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    BindingIdMark( uid )->marked = true;

	} else
	    kc_no_default_in_with( "v_markbindingid", __LINE__, __FILE__ );
    }

}

void v_resetbindingidmarks()
{
    if (Thebindingidmarks) {
	{
	    bindingidmarks kc_fe_selvar_1 =  Thebindingidmarks ;

	    while(
		    kc_fe_selvar_1->prod_sel() == sel_Consbindingidmarks
		) {
		bindingidmark kc_selvar_0_1 = kc_fe_selvar_1->bindingidmark_1;
		{
		    {
			{
			    const bindingidmark m = kc_selvar_0_1;

			    m->marked = false;

			}
		    }

		}
		kc_fe_selvar_1 = kc_fe_selvar_1->bindingidmarks_1;

	    }
	}
    }

}

patternrepresentations add_predicates_to_patternrepresentations(patternrepresentations a_patternreps)
{{
	patternrepresentations kc_selvar_0_1 = phylum_cast<patternrepresentations>(a_patternreps);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatternrepresentations)) {
	    const patternrepresentation a_patternrep = (kc_selvar_0_1)->patternrepresentation_1;
	    const patternrepresentations r_patternreps = (kc_selvar_0_1)->patternrepresentations_1;

	    patternrepresentation tmp;
	    v_resetbindingidmarks(); 
	    tmp = add_predicates( a_patternrep );
	    return Conspatternrepresentations(
		concat( a_patternrep, tmp ),
		add_predicates_to_patternrepresentations( r_patternreps )
	    );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternrepresentations)) {

	    return Nilpatternrepresentations();

	} else
	{ kc_no_default_in_with( "add_predicates_to_patternrepresentations", __LINE__, __FILE__ );
	    return static_cast<patternrepresentations>(0); }
    }

}

static  patternrepresentation add_predicates(patternrepresentation a_patternrep)
{{
	patternrepresentation kc_selvar_0_1 = phylum_cast<patternrepresentation>(a_patternrep);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatternrepresentation)) {
	    const elem_patternrepresentation a_pattern_rep_elem = (kc_selvar_0_1)->elem_patternrepresentation_1;
	    const patternrepresentation r_patternrep = (kc_selvar_0_1)->patternrepresentation_1;

	    patternrepresentation tmp_for_elem, tmp_for_rest;








	    tmp_for_elem = add_predicate( a_pattern_rep_elem, r_patternrep );
	    tmp_for_rest = add_predicates( r_patternrep );
	    return concat( tmp_for_elem, tmp_for_rest );


	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternrepresentation)) {

	    return Nilpatternrepresentation();

	} else
	{ kc_no_default_in_with( "add_predicates", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

static  patternrepresentation add_predicate(elem_patternrepresentation a_patternrep_elem, patternrepresentation a_patternrep)
{{
	elem_patternrepresentation kc_selvar_0_1 = phylum_cast<elem_patternrepresentation>(a_patternrep_elem);
	if ((kc_selvar_0_1->prod_sel() == sel_PRNonLeafBinding)) {
	    const ID id = phylum_cast<const impl_elem_patternrepresentation_PRNonLeafBinding*>(kc_selvar_0_1)->ID_1;

	    if (! f_bindingidmarked( id )) {
		v_markbindingid( id );
		return make_predicates( a_patternrep_elem, a_patternrep );
	    } else {
		return Nilpatternrepresentation();
	    }

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRBinding)) {
	    const ID id = phylum_cast<const impl_elem_patternrepresentation_PRBinding*>(kc_selvar_0_1)->ID_1;

	    if (! f_bindingidmarked( id )) {
		v_markbindingid( id );
		return make_predicates( a_patternrep_elem, a_patternrep );
	    } else {
		return Nilpatternrepresentation();
	    }

	} else
	{

	    return Nilpatternrepresentation();

	}
    }

}

static  patternrepresentation t_make_predicates(ID a_id, paths a_paths, patternrepresentation a_subpattern, patternrepresentation a_patternrep, bool left_linear)
{{
	patternrepresentation kc_selvar_0_1 = phylum_cast<patternrepresentation>(a_patternrep);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatternrepresentation)) {
	    const elem_patternrepresentation aps_patternrep_elem = (kc_selvar_0_1)->elem_patternrepresentation_1;
	    const patternrepresentation r_apatternrep = (kc_selvar_0_1)->patternrepresentation_1;

	    {
		elem_patternrepresentation kc_selvar_1_1 = phylum_cast<elem_patternrepresentation>( aps_patternrep_elem );
		if ((kc_selvar_1_1->prod_sel() == sel_PRNonLeafBinding)) {
		    const path aps_path = phylum_cast<const impl_elem_patternrepresentation_PRNonLeafBinding*>(kc_selvar_1_1)->path_1;
		    const ID aps_id = phylum_cast<const impl_elem_patternrepresentation_PRNonLeafBinding*>(kc_selvar_1_1)->ID_1;
		    const patternrepresentation aps_subpattern = phylum_cast<const impl_elem_patternrepresentation_PRNonLeafBinding*>(kc_selvar_1_1)->patternrepresentation_1;

		    if ( a_id->eq( aps_id )) {
			if ( test_matching_subpatterns( aps_subpattern, a_subpattern ) ) {
			    return t_make_predicates( a_id, Conspaths( aps_path, a_paths ), concat( aps_subpattern, a_subpattern ), r_apatternrep, false );
			} else {
			    return t_make_predicates( a_id, a_paths, a_subpattern, r_apatternrep, false );
			}
		    } else {
			return t_make_predicates( a_id, a_paths, a_subpattern, r_apatternrep, left_linear );
		    }

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_PRBinding)) {
		    const path aps_path = phylum_cast<const impl_elem_patternrepresentation_PRBinding*>(kc_selvar_1_1)->path_1;
		    const ID aps_id = phylum_cast<const impl_elem_patternrepresentation_PRBinding*>(kc_selvar_1_1)->ID_1;

		    if ( a_id->eq( aps_id )) {
			return t_make_predicates( a_id, Conspaths( aps_path, a_paths ), a_subpattern, r_apatternrep, false );
		    } else {
			return t_make_predicates( a_id, a_paths, a_subpattern, r_apatternrep, left_linear );
		    }

		} else
		{

		    return t_make_predicates( a_id, a_paths, a_subpattern, r_apatternrep, left_linear );

		}
	    }

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternrepresentation)) {

	    if (left_linear) {
		return Nilpatternrepresentation();
	    } else {
		elem_patternrepresentation pred = PRVarPredicate(a_paths, a_id, a_subpattern);
		pred->file = a_id->file, pred->line = a_id->line;
		return Conspatternrepresentation( pred, Nilpatternrepresentation() );
	    }

	} else
	{ kc_no_default_in_with( "t_make_predicates", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

static  patternrepresentation make_predicates(elem_patternrepresentation a_patternrep_elem, patternrepresentation a_patternrep)
{{
	elem_patternrepresentation kc_selvar_0_1 = phylum_cast<elem_patternrepresentation>(a_patternrep_elem);
	if ((kc_selvar_0_1->prod_sel() == sel_PRNonLeafBinding)) {
	    const path a_path = phylum_cast<const impl_elem_patternrepresentation_PRNonLeafBinding*>(kc_selvar_0_1)->path_1;
	    const ID a_id = phylum_cast<const impl_elem_patternrepresentation_PRNonLeafBinding*>(kc_selvar_0_1)->ID_1;
	    const patternrepresentation a_subpattern = phylum_cast<const impl_elem_patternrepresentation_PRNonLeafBinding*>(kc_selvar_0_1)->patternrepresentation_1;

	    return t_make_predicates( a_id, Conspaths( a_path, Nilpaths()), a_subpattern, a_patternrep, true );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRBinding)) {
	    const path a_path = phylum_cast<const impl_elem_patternrepresentation_PRBinding*>(kc_selvar_0_1)->path_1;
	    const ID a_id = phylum_cast<const impl_elem_patternrepresentation_PRBinding*>(kc_selvar_0_1)->ID_1;

	    return t_make_predicates( a_id, Conspaths( a_path, Nilpaths()), Nilpatternrepresentation(), a_patternrep, true );

	} else
	{ kc_no_default_in_with( "make_predicates", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

static  bool test_matching_subpatterns(patternrepresentation newp, patternrepresentation oldp)
{
    return true;

}

void v_add_rewriterulesinfo_to_operator(patternrepresentations a_patternreps, rewriteclauses rc)
{
    {
	patternrepresentations kc_fe_selvar_1 =  a_patternreps ;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Conspatternrepresentations
	    ) {
	    patternrepresentation kc_selvar_0_1 = kc_fe_selvar_1->patternrepresentation_1;
	    {
		{
		    {
			const patternrepresentation a_patternrep = kc_selvar_0_1;

			ID op = f_operatorofpatternrepresentation( a_patternrep );
			if (! op->eq( f_emptyId() )) {
			    alternative a = f_alternativeofoperator(op);
			    if (a) {
				{
				    rewriteclauses kc_fe_selvar_1 =  rc ;

				    while(
					    kc_fe_selvar_1->prod_sel() == sel_Consrewriteclauses
					) {
					rewriteclause kc_selvar_1_1 = kc_fe_selvar_1->rewriteclause_1;
					{
					    {
						{
						    const rewriteclause r = kc_selvar_1_1;


						    a->rewriteinfo = insertin_rewriterulesinfo( Rewriteruleinfo( f_get_predicates( a_patternrep ), f_get_bindings( a_patternrep ), r ), a->rewriteinfo );

						}
					    }

					}
					kc_fe_selvar_1 = kc_fe_selvar_1->rewriteclauses_1;

				    }
				}
			    }   }   
		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->patternrepresentations_1;

	}
    }

}

withcasesinfo f_withcasesinfo(patternrepresentations a_patternreps, Ctext ct)
{
    withcasesinfo tmp = Nilwithcasesinfo();
    {
	patternrepresentations kc_fe_selvar_1 =  a_patternreps ;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Conspatternrepresentations
	    ) {
	    patternrepresentation kc_selvar_0_1 = kc_fe_selvar_1->patternrepresentation_1;
	    {
		{
		    {
			const patternrepresentation a_patternrep = kc_selvar_0_1;

			{
			    patternrepresentation kc_selvar_1_1 = phylum_cast<patternrepresentation>( a_patternrep );
			    if ((kc_selvar_1_1->prod_sel() == sel_Conspatternrepresentation)) {

				tmp = insertin_withcasesinfo( Withcaseinfo( f_get_predicates( a_patternrep ), f_get_bindings( a_patternrep ), ct ), tmp );

			    } else
				if ((kc_selvar_1_1->prod_sel() == sel_Nilpatternrepresentation)) {
				/*EMPTY*/
					} else
			    { kc_no_default_in_with( "f_withcasesinfo", __LINE__, __FILE__ );
				return static_cast<withcasesinfo>(0); }
			}

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->patternrepresentations_1;

	}
    }
    return tmp;

}

void v_add_unparsedeclsinfo_to_operator(patternrepresentations a_patternreps, unparseclauses uc)
{
    {
	patternrepresentations kc_fe_selvar_1 =  a_patternreps ;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Conspatternrepresentations
	    ) {
	    patternrepresentation kc_selvar_0_1 = kc_fe_selvar_1->patternrepresentation_1;
	    {
		{
		    {
			const patternrepresentation a_patternrep = kc_selvar_0_1;

			ID op = f_operatorofpatternrepresentation( a_patternrep );
			if (! op->eq( f_emptyId() )) {
			    alternative a = f_alternativeofoperator(op);
			    if (a) {
				{
				    unparseclauses kc_fe_selvar_1 =  uc ;

				    while(
					    kc_fe_selvar_1->prod_sel() == sel_Consunparseclauses
					) {
					unparseclause kc_selvar_1_1 = kc_fe_selvar_1->unparseclause_1;
					{
					    {
						{
						    const unparseclause u = kc_selvar_1_1;


						    a->unparseinfo = insertin_unparsedeclsinfo( Unparsedeclinfo( f_get_predicates( a_patternrep ), f_get_bindings( a_patternrep ), u ), a->unparseinfo );

						}
					    }

					}
					kc_fe_selvar_1 = kc_fe_selvar_1->unparseclauses_1;

				    }
				}
			    }   }   
		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->patternrepresentations_1;

	}
    }

}

static  patternrepresentation f_get_predicates(patternrepresentation a_patternrep)
{{
	patternrepresentation kc_selvar_0_1 = phylum_cast<patternrepresentation>(a_patternrep);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatternrepresentation)) {
	    const elem_patternrepresentation a_patternrep_elem = (kc_selvar_0_1)->elem_patternrepresentation_1;
	    const patternrepresentation r_patternrep = (kc_selvar_0_1)->patternrepresentation_1;

	    {
		elem_patternrepresentation kc_selvar_1_1 = phylum_cast<elem_patternrepresentation>( a_patternrep_elem );
		if ((kc_selvar_1_1->prod_sel() == sel_PRNonLeafBinding)) {

		    return f_get_predicates( r_patternrep );

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_PRBinding)) {

		    return f_get_predicates( r_patternrep );

		} else
		{

		    return Conspatternrepresentation( a_patternrep_elem, f_get_predicates( r_patternrep ) );

		}
	    }

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternrepresentation)) {

	    return Nilpatternrepresentation();

	} else
	{ kc_no_default_in_with( "f_get_predicates", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

static  patternrepresentation f_get_bindings(patternrepresentation a_patternrep)
{
    patternrepresentation p;
    v_resetbindingidmarks();
    p = f_do_get_bindings( a_patternrep );
    v_resetbindingidmarks();
    return p;

}

static  patternrepresentation f_do_get_bindings(patternrepresentation a_patternrep)
{{
	patternrepresentation kc_selvar_0_1 = phylum_cast<patternrepresentation>(a_patternrep);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatternrepresentation)) {
	    const elem_patternrepresentation a_patternrep_elem = (kc_selvar_0_1)->elem_patternrepresentation_1;
	    const patternrepresentation r_patternrep = (kc_selvar_0_1)->patternrepresentation_1;

	    {
		elem_patternrepresentation kc_selvar_1_1 = phylum_cast<elem_patternrepresentation>( a_patternrep_elem );
		if ((kc_selvar_1_1->prod_sel() == sel_PRNonLeafBinding)) {
		    const ID id = phylum_cast<const impl_elem_patternrepresentation_PRNonLeafBinding*>(kc_selvar_1_1)->ID_1;

		    if (! f_bindingidmarked( id )) {
			v_markbindingid( id );
			return Conspatternrepresentation( a_patternrep_elem, f_do_get_bindings( r_patternrep ) );
		    } else {
			return f_do_get_bindings( r_patternrep );
		    }   
		    	} else
		    if ((kc_selvar_1_1->prod_sel() == sel_PRBinding)) {
		    const ID id = phylum_cast<const impl_elem_patternrepresentation_PRBinding*>(kc_selvar_1_1)->ID_1;

		    if (! f_bindingidmarked( id )) {
			v_markbindingid( id );
			return Conspatternrepresentation( a_patternrep_elem, f_do_get_bindings( r_patternrep ) );
		    } else {
			return f_do_get_bindings( r_patternrep );
		    }   
		    	} else
		{

		    return f_do_get_bindings( r_patternrep );

		}
	    }

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternrepresentation)) {

	    return Nilpatternrepresentation();

	} else
	{ kc_no_default_in_with( "f_do_get_bindings", __LINE__, __FILE__ );
	    return static_cast<patternrepresentation>(0); }
    }

}

static  rewriterulesinfo insertin_rewriterulesinfo(rewriteruleinfo new_rule, rewriterulesinfo old_rules)
{{
	rewriterulesinfo kc_selvar_0_1 = phylum_cast<rewriterulesinfo>(old_rules);
	if ((kc_selvar_0_1->prod_sel() == sel_Consrewriterulesinfo)) {
	    const rewriteruleinfo head_rule = (kc_selvar_0_1)->rewriteruleinfo_1;
	    const rewriterulesinfo rest_rules = (kc_selvar_0_1)->rewriterulesinfo_1;

	    if (lt_rewriteruleinfo( head_rule, new_rule )) {
		return Consrewriterulesinfo( head_rule, insertin_rewriterulesinfo( new_rule, rest_rules ));
	    } else {
		return Consrewriterulesinfo( new_rule, old_rules );
	    }   
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilrewriterulesinfo)) {

	    return Consrewriterulesinfo( new_rule, old_rules );

	} else
	{ kc_no_default_in_with( "insertin_rewriterulesinfo", __LINE__, __FILE__ );
	    return static_cast<rewriterulesinfo>(0); }
    }

}

static  bool lt_rewriteruleinfo(rewriteruleinfo a_rwruleinfo1, rewriteruleinfo a_rwruleinfo2)
{{
	rewriteruleinfo kc_selvar_0_1 = phylum_cast<rewriteruleinfo>(a_rwruleinfo1);
	rewriteruleinfo kc_selvar_0_2 = phylum_cast<rewriteruleinfo>(a_rwruleinfo2);
	if ((kc_selvar_0_1->prod_sel() == sel_Rewriteruleinfo) && (kc_selvar_0_2->prod_sel() == sel_Rewriteruleinfo)) {
	    const patternrepresentation a_patternrep1 = phylum_cast<const impl_rewriteruleinfo_Rewriteruleinfo*>(kc_selvar_0_1)->patternrepresentation_1;
	    const patternrepresentation a_patternrep2 = phylum_cast<const impl_rewriteruleinfo_Rewriteruleinfo*>(kc_selvar_0_2)->patternrepresentation_1;

	    return lt_patternrepresentation( a_patternrep1, a_patternrep2 );

	} else
	{ kc_no_default_in_with( "lt_rewriteruleinfo", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

withcasesinfo insertin_withcasesinfo(withcaseinfo new_case, withcasesinfo old_cases)
{{
	withcasesinfo kc_selvar_0_1 = phylum_cast<withcasesinfo>(old_cases);
	if ((kc_selvar_0_1->prod_sel() == sel_Conswithcasesinfo)) {
	    const withcaseinfo head_case = (kc_selvar_0_1)->withcaseinfo_1;
	    const withcasesinfo rest_cases = (kc_selvar_0_1)->withcasesinfo_1;

	    if (lt_withcaseinfo( head_case, new_case )) {
		return Conswithcasesinfo( head_case, insertin_withcasesinfo( new_case, rest_cases ));
	    } else {
		return Conswithcasesinfo( new_case, old_cases );
	    }   
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilwithcasesinfo)) {

	    return Conswithcasesinfo( new_case, old_cases );

	} else
	{ kc_no_default_in_with( "insertin_withcasesinfo", __LINE__, __FILE__ );
	    return static_cast<withcasesinfo>(0); }
    }

}

bool lt_withcaseinfo(withcaseinfo a_withcaseinfo1, withcaseinfo a_withcaseinfo2)
{{
	withcaseinfo kc_selvar_0_1 = phylum_cast<withcaseinfo>(a_withcaseinfo1);
	withcaseinfo kc_selvar_0_2 = phylum_cast<withcaseinfo>(a_withcaseinfo2);
	if ((kc_selvar_0_1->prod_sel() == sel_Withcaseinfo) && (kc_selvar_0_2->prod_sel() == sel_Withcaseinfo)) {
	    const patternrepresentation a_patternrep1 = phylum_cast<const impl_withcaseinfo_Withcaseinfo*>(kc_selvar_0_1)->patternrepresentation_1;
	    const patternrepresentation a_patternrep2 = phylum_cast<const impl_withcaseinfo_Withcaseinfo*>(kc_selvar_0_2)->patternrepresentation_1;

	    return lt_patternrepresentation( a_patternrep1, a_patternrep2 );

	} else
	{ kc_no_default_in_with( "lt_withcaseinfo", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

static  unparsedeclsinfo insertin_unparsedeclsinfo(unparsedeclinfo new_decl, unparsedeclsinfo old_decls)
{{
	unparsedeclsinfo kc_selvar_0_1 = phylum_cast<unparsedeclsinfo>(old_decls);
	if ((kc_selvar_0_1->prod_sel() == sel_Consunparsedeclsinfo)) {
	    const unparsedeclinfo head_decl = (kc_selvar_0_1)->unparsedeclinfo_1;
	    const unparsedeclsinfo rest_decls = (kc_selvar_0_1)->unparsedeclsinfo_1;

	    if (lt_unparsedeclinfo( head_decl, new_decl )) {
		return Consunparsedeclsinfo( head_decl, insertin_unparsedeclsinfo( new_decl, rest_decls ));
	    } else {
		return Consunparsedeclsinfo( new_decl, old_decls );
	    }   
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilunparsedeclsinfo)) {

	    return Consunparsedeclsinfo( new_decl, old_decls );

	} else
	{ kc_no_default_in_with( "insertin_unparsedeclsinfo", __LINE__, __FILE__ );
	    return static_cast<unparsedeclsinfo>(0); }
    }

}

static  bool lt_unparsedeclinfo(unparsedeclinfo a_unparsedeclinfo1, unparsedeclinfo a_unparsedeclinfo2)
{{
	unparsedeclinfo kc_selvar_0_1 = phylum_cast<unparsedeclinfo>(a_unparsedeclinfo1);
	unparsedeclinfo kc_selvar_0_2 = phylum_cast<unparsedeclinfo>(a_unparsedeclinfo2);
	if ((kc_selvar_0_1->prod_sel() == sel_Unparsedeclinfo) && (kc_selvar_0_2->prod_sel() == sel_Unparsedeclinfo)) {
	    const patternrepresentation a_patternrep1 = phylum_cast<const impl_unparsedeclinfo_Unparsedeclinfo*>(kc_selvar_0_1)->patternrepresentation_1;
	    const patternrepresentation a_patternrep2 = phylum_cast<const impl_unparsedeclinfo_Unparsedeclinfo*>(kc_selvar_0_2)->patternrepresentation_1;

	    return lt_patternrepresentation( a_patternrep1, a_patternrep2 );

	} else
	{ kc_no_default_in_with( "lt_unparsedeclinfo", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

void warn_drop_identical_pattern(rewriteruleinfo rri)
{{
	rewriteruleinfo kc_selvar_0_1 = phylum_cast<rewriteruleinfo>(rri);
	if ((kc_selvar_0_1->prod_sel() == sel_Rewriteruleinfo)) {
	    const patternrepresentation pr = phylum_cast<const impl_rewriteruleinfo_Rewriteruleinfo*>(kc_selvar_0_1)->patternrepresentation_1;
	    warn_drop_identical_pattern(pr); 
	    	} else
	    kc_no_default_in_with( "warn_drop_identical_pattern", __LINE__, __FILE__ );
    }

}

void warn_drop_identical_pattern(withcaseinfo wci)
{{
	withcaseinfo kc_selvar_0_1 = phylum_cast<withcaseinfo>(wci);
	if ((kc_selvar_0_1->prod_sel() == sel_Withcaseinfo)) {
	    const patternrepresentation pr = phylum_cast<const impl_withcaseinfo_Withcaseinfo*>(kc_selvar_0_1)->patternrepresentation_1;
	    warn_drop_identical_pattern(pr); 
	    	} else
	    kc_no_default_in_with( "warn_drop_identical_pattern", __LINE__, __FILE__ );
    }

}

void warn_drop_identical_pattern(unparsedeclinfo udi)
{{
	unparsedeclinfo kc_selvar_0_1 = phylum_cast<unparsedeclinfo>(udi);
	if ((kc_selvar_0_1->prod_sel() == sel_Unparsedeclinfo)) {
	    const patternrepresentation pr = phylum_cast<const impl_unparsedeclinfo_Unparsedeclinfo*>(kc_selvar_0_1)->patternrepresentation_1;
	    warn_drop_identical_pattern(pr); 
	    	} else
	    kc_no_default_in_with( "warn_drop_identical_pattern", __LINE__, __FILE__ );
    }

}

void warn_drop_identical_pattern(patternrepresentation pr)
{{
	patternrepresentation kc_selvar_0_1 = phylum_cast<patternrepresentation>(pr);
	if ((kc_selvar_0_1->prod_sel() == sel_Conspatternrepresentation)) {
	    const elem_patternrepresentation epr = (kc_selvar_0_1)->elem_patternrepresentation_1;

	    v_report(Warning(FileLine( epr->file, epr->line ),
		    Problem1S("Warning: dropped pattern")));

	} else
	{

	    assertionFailed("Dropping empty pattern");

	}
    }

}

static  bool lt_patternrepresentation(patternrepresentation pr1, patternrepresentation pr2)
{
    {
	patternrepresentation kc_fe_selvar_1 =  pr1;
	patternrepresentation kc_fe_selvar_2 =  pr2;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Conspatternrepresentation
		&& kc_fe_selvar_2->prod_sel() == sel_Conspatternrepresentation
	    ) {
	    elem_patternrepresentation kc_selvar_0_1 = kc_fe_selvar_1->elem_patternrepresentation_1;
	    elem_patternrepresentation kc_selvar_0_2 = kc_fe_selvar_2->elem_patternrepresentation_1;
	    {
		{
		    {
			const elem_patternrepresentation p1 = kc_selvar_0_1;
			const elem_patternrepresentation p2 = kc_selvar_0_2;

			{
			    tribool kc_selvar_1_1 = phylum_cast<tribool>( equal_elem_patternrepresentation(p1, p2) );
			    if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {
				return false; 
					} else
				if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {
				return true; 
					} else
			    {

			    }
			}

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->patternrepresentation_1;
	    kc_fe_selvar_2 = kc_fe_selvar_2->patternrepresentation_1;

	}
	{
	    {
		{
		    const patternrepresentation re1 = kc_fe_selvar_1;
		    const patternrepresentation re2 = kc_fe_selvar_2;
		    {
			patternrepresentation kc_selvar_1_1 = phylum_cast<patternrepresentation>(re1);
			patternrepresentation kc_selvar_1_2 = phylum_cast<patternrepresentation>(re2);
			if ((kc_selvar_1_1->prod_sel() == sel_Nilpatternrepresentation) && (kc_selvar_1_2->prod_sel() == sel_Nilpatternrepresentation)) {
			    return false; 
			    	} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Nilpatternrepresentation)) {
			    return false; 
			    	} else
			    if ((kc_selvar_1_2->prod_sel() == sel_Nilpatternrepresentation)) {
			    return true; 
			    	} else
			{ kc_no_default_in_with( "lt_patternrepresentation", __LINE__, __FILE__ );
			    return static_cast<bool>(0); }
		    }

		}
	    }

	}
    }

}

static  tribool equal_elem_patternrepresentation(elem_patternrepresentation a_patternrep_elem1, elem_patternrepresentation a_patternrep_elem2)
{{
	elem_patternrepresentation kc_selvar_0_1 = phylum_cast<elem_patternrepresentation>(a_patternrep_elem1);
	elem_patternrepresentation kc_selvar_0_2 = phylum_cast<elem_patternrepresentation>(a_patternrep_elem2);
	if ((kc_selvar_0_1->prod_sel() == sel_PRDefault) && (kc_selvar_0_2->prod_sel() == sel_PRWildcard)) {
	    return Bigger(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRWildcard) && (kc_selvar_0_2->prod_sel() == sel_PRDefault)) {
	    return Smaller(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRVarPredicate) && (kc_selvar_0_2->prod_sel() == sel_PROperPredicate)) {
	    return Bigger(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PROperPredicate) && (kc_selvar_0_2->prod_sel() == sel_PRVarPredicate)) {
	    return Smaller(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRVarPredicate) && (kc_selvar_0_2->prod_sel() == sel_PRIntLiteral)) {
	    return Bigger(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRIntLiteral) && (kc_selvar_0_2->prod_sel() == sel_PRVarPredicate)) {
	    return Smaller(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRVarPredicate) && (kc_selvar_0_2->prod_sel() == sel_PRStringLiteral)) {
	    return Bigger(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRStringLiteral) && (kc_selvar_0_2->prod_sel() == sel_PRVarPredicate)) {
	    return Smaller(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRIntLiteral) && (kc_selvar_0_2->prod_sel() == sel_PRStringLiteral)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRStringLiteral) && (kc_selvar_0_2->prod_sel() == sel_PRIntLiteral)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PROperPredicate) && (kc_selvar_0_2->prod_sel() == sel_PRIntLiteral)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRIntLiteral) && (kc_selvar_0_2->prod_sel() == sel_PROperPredicate)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PROperPredicate) && (kc_selvar_0_2->prod_sel() == sel_PRStringLiteral)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRStringLiteral) && (kc_selvar_0_2->prod_sel() == sel_PROperPredicate)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRIntLiteral) && (kc_selvar_0_2->prod_sel() == sel_PRIntLiteral)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRStringLiteral) && (kc_selvar_0_2->prod_sel() == sel_PRStringLiteral)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRNonLeafBinding) && (kc_selvar_0_2->prod_sel() == sel_PRNonLeafBinding)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRNonLeafBinding*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRNonLeafBinding*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRBinding) && (kc_selvar_0_2->prod_sel() == sel_PRBinding)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRBinding*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRBinding*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRWildcard) && (kc_selvar_0_2->prod_sel() == sel_PRWildcard)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRWildcard*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRWildcard*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PROperPredicate) && (kc_selvar_0_2->prod_sel() == sel_PROperPredicate)) {
	    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_1)->path_1;
	    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_2)->path_1;

	    return equal_path( a_path1, a_path2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRVarPredicate) && (kc_selvar_0_2->prod_sel() == sel_PRVarPredicate)) {
	    const paths a_paths1 = phylum_cast<const impl_elem_patternrepresentation_PRVarPredicate*>(kc_selvar_0_1)->paths_1;
	    const paths a_paths2 = phylum_cast<const impl_elem_patternrepresentation_PRVarPredicate*>(kc_selvar_0_2)->paths_1;

	    return equal_paths( a_paths1, a_paths2 );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRUserPredicate) && (kc_selvar_0_2->prod_sel() == sel_PRUserPredicate)) {

	    return Equal();

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRDefault) && (kc_selvar_0_2->prod_sel() == sel_PRDefault)) {

	    return Equal();

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRUserPredicate)) {
	    return Bigger(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRNonLeafBinding)) {
	    return Bigger(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRBinding)) {
	    return Bigger(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRWildcard)) {
	    return Bigger(); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_PRDefault)) {
	    return Bigger(); 
	    	} else
	    if ((kc_selvar_0_2->prod_sel() == sel_PRUserPredicate)) {
	    return Smaller(); 
	    	} else
	    if ((kc_selvar_0_2->prod_sel() == sel_PRNonLeafBinding)) {
	    return Smaller(); 
	    	} else
	    if ((kc_selvar_0_2->prod_sel() == sel_PRBinding)) {
	    return Smaller(); 
	    	} else
	    if ((kc_selvar_0_2->prod_sel() == sel_PRWildcard)) {
	    return Smaller(); 
	    	} else
	    if ((kc_selvar_0_2->prod_sel() == sel_PRDefault)) {
	    return Smaller(); 
	    	} else
	{ kc_no_default_in_with( "equal_elem_patternrepresentation", __LINE__, __FILE__ );
	    return static_cast<tribool>(0); }
    }

}

static  tribool equal_path(path a_path1, path a_path2)
{
    path r_a_path1=a_path1->reverse(), r_a_path2=a_path2->reverse();
    tribool ret;
    bool breakforeach = false;
    {
	path kc_fe_selvar_1 =  r_a_path1;
	path kc_fe_selvar_2 =  r_a_path2;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Conspath
		&& kc_fe_selvar_2->prod_sel() == sel_Conspath
	    ) {
	    integer kc_selvar_0_1 = kc_fe_selvar_1->integer_1;
	    integer kc_selvar_0_2 = kc_fe_selvar_2->integer_1;
	    {
		{
		    {
			const integer i1 = kc_selvar_0_1;
			const integer i2 = kc_selvar_0_2;

			if (!breakforeach)
			if ( i1->value < i2->value )
			ret = Smaller(), breakforeach = true;
			else if (i1->value > i2->value )
			ret = Bigger(), breakforeach = true;

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->path_1;
	    kc_fe_selvar_2 = kc_fe_selvar_2->path_1;

	}
	{
	    {
		{
		    const path re1 = kc_fe_selvar_1;
		    const path re2 = kc_fe_selvar_2;
		    {
			path kc_selvar_1_1 = phylum_cast<path>(re1);
			path kc_selvar_1_2 = phylum_cast<path>(re2);
			if ((kc_selvar_1_1->prod_sel() == sel_Nilpath) && (kc_selvar_1_2->prod_sel() == sel_Conspath)) {
			    ret = breakforeach ? ret : Bigger(); 
			    	} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Conspath) && (kc_selvar_1_2->prod_sel() == sel_Nilpath)) {
			    ret = breakforeach ? ret : Smaller(); 
			    	} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Nilpath) && (kc_selvar_1_2->prod_sel() == sel_Nilpath)) {
			    ret = breakforeach ? ret : Equal(); 
			    	} else
			{ kc_no_default_in_with( "equal_path", __LINE__, __FILE__ );
			    return static_cast<tribool>(0); }
		    }

		}
	    }

	}
    }
    r_a_path1->freelist(); r_a_path2->freelist();
    return ret;

}

static  tribool equal_paths(paths a_paths1, paths a_paths2)
{
    {
	paths kc_fe_selvar_1 =  a_paths1;
	paths kc_fe_selvar_2 =  a_paths2;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Conspaths
		&& kc_fe_selvar_2->prod_sel() == sel_Conspaths
	    ) {
	    path kc_selvar_0_1 = kc_fe_selvar_1->path_1;
	    path kc_selvar_0_2 = kc_fe_selvar_2->path_1;
	    {
		{
		    {
			const path path1 = kc_selvar_0_1;
			const path path2 = kc_selvar_0_2;

			{
			    tribool kc_selvar_1_1 = phylum_cast<tribool>( equal_path( path1, path2 ) );
			    if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {
				return Bigger(); 
					} else
				if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {
				return Smaller(); 
					} else
			    {

			    }
			}

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->paths_1;
	    kc_fe_selvar_2 = kc_fe_selvar_2->paths_1;

	}
	{
	    {
		{
		    const paths re1 = kc_fe_selvar_1;
		    const paths re2 = kc_fe_selvar_2;
		    {
			paths kc_selvar_1_1 = phylum_cast<paths>(re1);
			paths kc_selvar_1_2 = phylum_cast<paths>(re2);
			if ((kc_selvar_1_1->prod_sel() == sel_Nilpaths) && (kc_selvar_1_2->prod_sel() == sel_Conspaths)) {
			    return Bigger(); 
			    	} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Conspaths) && (kc_selvar_1_2->prod_sel() == sel_Nilpaths)) {
			    return Smaller(); 
			    	} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Nilpaths) && (kc_selvar_1_2->prod_sel() == sel_Nilpaths)) {
			    return Equal(); 
			    	} else
			{ kc_no_default_in_with( "equal_paths", __LINE__, __FILE__ );
			    return static_cast<tribool>(0); }
		    }

		}
	    }

	}
    }

}

void check_rewrite_patterns(rewriterulesinfo rri)
{
    elem_patternrepresentation outmost_nl = f_outmost_nl_preds_in_rewriterulesinfo(rri);
    if (outmost_nl)
    v_report(Warning(FileLine( outmost_nl->file, outmost_nl->line ),
	    Problem1S("Cannot handle outmost non-leaf predicates")));

    patternrepresentations prs = Nilpatternrepresentations();

    {
	rewriterulesinfo kc_fe_selvar_1 =  rri;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Consrewriterulesinfo
	    ) {
	    rewriteruleinfo kc_selvar_0_1 = kc_fe_selvar_1->rewriteruleinfo_1;
	    {
		{
		    if ((kc_selvar_0_1->prod_sel() == sel_Rewriteruleinfo)) {
			const patternrepresentation pr = phylum_cast<const impl_rewriteruleinfo_Rewriteruleinfo*>(kc_selvar_0_1)->patternrepresentation_1;

			prs = Conspatternrepresentations(pr, prs);

		    } else
		    {/* EMPTY */ /*skip: no matching pattern in foreach patterns*/}
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->rewriterulesinfo_1;

	}
    }
    check_patterns(prs);
    prs->freelist();

}

void check_with_patterns(withcasesinfo wcs)
{
    patternrepresentations prs = Nilpatternrepresentations(), prs_rev;

    {
	withcasesinfo kc_fe_selvar_1 =  wcs;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Conswithcasesinfo
	    ) {
	    withcaseinfo kc_selvar_0_1 = kc_fe_selvar_1->withcaseinfo_1;
	    {
		{
		    if ((kc_selvar_0_1->prod_sel() == sel_Withcaseinfo)) {
			const patternrepresentation pr = phylum_cast<const impl_withcaseinfo_Withcaseinfo*>(kc_selvar_0_1)->patternrepresentation_1;

			prs = Conspatternrepresentations(pr, prs);

		    } else
		    {/* EMPTY */ /*skip: no matching pattern in foreach patterns*/}
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->withcasesinfo_1;

	}
    }
    prs_rev=prs->reverse();
    check_patterns(prs_rev);
    prs->freelist();
    prs_rev->freelist();

}

void check_unparse_patterns(unparsedeclsinfo udi)
{
    elem_patternrepresentation outmost_nl = f_outmost_nl_preds_in_unparsedeclsinfo(udi);
    if (outmost_nl)
    v_report(Warning(FileLine( outmost_nl->file, outmost_nl->line ),
	    Problem1S("Cannot handle outmost non-leaf predicates")));

    patternrepresentations prs = Nilpatternrepresentations();

    {
	unparsedeclsinfo kc_fe_selvar_1 =  udi;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Consunparsedeclsinfo
	    ) {
	    unparsedeclinfo kc_selvar_0_1 = kc_fe_selvar_1->unparsedeclinfo_1;
	    {
		{
		    if ((kc_selvar_0_1->prod_sel() == sel_Unparsedeclinfo)) {
			const patternrepresentation pr = phylum_cast<const impl_unparsedeclinfo_Unparsedeclinfo*>(kc_selvar_0_1)->patternrepresentation_1;

			prs = Conspatternrepresentations(pr, prs);

		    } else
		    {/* EMPTY */ /*skip: no matching pattern in foreach patterns*/}
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->unparsedeclsinfo_1;

	}
    }
    check_patterns(prs);
    prs->freelist();

}

void check_patterns(patternrepresentations prs)
{

    if (prs->is_nil() || prs->patternrepresentations_1->is_nil()) return;

    patternrepresentations iterate = prs;

    while (!prs->patternrepresentations_1->is_nil()) {
	{
	    patternrepresentations kc_fe_selvar_1 =  prs->patternrepresentations_1;

	    while(
		    kc_fe_selvar_1->prod_sel() == sel_Conspatternrepresentations
		) {
		patternrepresentation kc_selvar_0_1 = kc_fe_selvar_1->patternrepresentation_1;
		{
		    {
			{
			    const patternrepresentation pr2 = kc_selvar_0_1;

			    compare_patterns(prs->patternrepresentation_1, pr2, prs);

			}
		    }

		}
		kc_fe_selvar_1 = kc_fe_selvar_1->patternrepresentations_1;

	    }
	}
	prs=prs->patternrepresentations_1;
    }



}

patternrepresentation next(patternrepresentation p)
{ return p->patternrepresentation_1; 
}

elem_patternrepresentation elem(patternrepresentation p)
{ return p->elem_patternrepresentation_1; 
}

void compare_patterns(patternrepresentation pr1, patternrepresentation pr2, patternrepresentations other_patterns)
{
    bool pr1_isMoreSpecific = false, pr2_isMoreSpecific = false;
    elem_patternrepresentation epr1 = elem(pr1), epr2 = elem(pr2);
    patternrepresentation i1 = pr1, i2 = pr2, intersection = Nilpatternrepresentation();

    while(!(i1->is_nil() || i2->is_nil())) {
	if (elem(i1)->eq(elem(i2))) {
	    intersection->append(elem(i1));
	    i1=next(i1);
	    i2=next(i2);
	}
	else {
	    {
		elem_patternrepresentation kc_selvar_0_1 = phylum_cast<elem_patternrepresentation>(elem(i1));
		elem_patternrepresentation kc_selvar_0_2 = phylum_cast<elem_patternrepresentation>( elem(i2));
		if ((kc_selvar_0_1->prod_sel() == sel_PRWildcard) && (kc_selvar_0_2->prod_sel() == sel_PRWildcard)) {

		    if(g_options.verbose) {
			printf("Don't know how to compare these yet:\n");
			printf("%s:%d ", epr1->file->name, epr1->line); elem(i1)->print();
			printf("%s:%d ", epr2->file->name, epr2->line); elem(i2)->print();
		    }
		    return;

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PRDefault) && (kc_selvar_0_2->prod_sel() == sel_PRDefault)) {

		    if(g_options.verbose) {
			printf("Don't know how to compare these yet:\n");
			printf("%s:%d ", epr1->file->name, epr1->line); elem(i1)->print();
			printf("%s:%d ", epr2->file->name, epr2->line); elem(i2)->print();
		    }
		    return;

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PRIntLiteral) && (kc_selvar_0_2->prod_sel() == sel_PRStringLiteral)) {
		    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_1)->path_1;
		    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_2)->path_1;

		    {
			tribool kc_selvar_1_1 = phylum_cast<tribool>(equal_path( a_path1, a_path2 ));
			if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {

			    pr2_isMoreSpecific=true;
			    intersection->append(elem(i2));
			    i2=next(i2);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {

			    pr1_isMoreSpecific=true;
			    intersection->append(elem(i1));
			    i1=next(i1);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Equal)) {

			    return; 
			    	} else
			    kc_no_default_in_with( "compare_patterns", __LINE__, __FILE__ );
		    }

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PRStringLiteral) && (kc_selvar_0_2->prod_sel() == sel_PRIntLiteral)) {
		    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_1)->path_1;
		    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_2)->path_1;

		    {
			tribool kc_selvar_1_1 = phylum_cast<tribool>(equal_path( a_path1, a_path2 ));
			if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {

			    pr2_isMoreSpecific=true;
			    intersection->append(elem(i2));
			    i2=next(i2);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {

			    pr1_isMoreSpecific=true;
			    intersection->append(elem(i1));
			    i1=next(i1);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Equal)) {

			    return; 
			    	} else
			    kc_no_default_in_with( "compare_patterns", __LINE__, __FILE__ );
		    }

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PROperPredicate) && (kc_selvar_0_2->prod_sel() == sel_PRIntLiteral)) {
		    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_1)->path_1;
		    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_2)->path_1;

		    {
			tribool kc_selvar_1_1 = phylum_cast<tribool>(equal_path( a_path1, a_path2 ));
			if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {

			    pr2_isMoreSpecific=true;
			    intersection->append(elem(i2));
			    i2=next(i2);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {

			    pr1_isMoreSpecific=true;
			    intersection->append(elem(i1));
			    i1=next(i1);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Equal)) {

			    return; 
			    	} else
			    kc_no_default_in_with( "compare_patterns", __LINE__, __FILE__ );
		    }

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PRIntLiteral) && (kc_selvar_0_2->prod_sel() == sel_PROperPredicate)) {
		    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_1)->path_1;
		    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_2)->path_1;

		    {
			tribool kc_selvar_1_1 = phylum_cast<tribool>(equal_path( a_path1, a_path2 ));
			if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {

			    pr2_isMoreSpecific=true;
			    intersection->append(elem(i2));
			    i2=next(i2);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {

			    pr1_isMoreSpecific=true;
			    intersection->append(elem(i1));
			    i1=next(i1);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Equal)) {

			    return; 
			    	} else
			    kc_no_default_in_with( "compare_patterns", __LINE__, __FILE__ );
		    }

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PROperPredicate) && (kc_selvar_0_2->prod_sel() == sel_PRStringLiteral)) {
		    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_1)->path_1;
		    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_2)->path_1;

		    {
			tribool kc_selvar_1_1 = phylum_cast<tribool>(equal_path( a_path1, a_path2 ));
			if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {

			    pr2_isMoreSpecific=true;
			    intersection->append(elem(i2));
			    i2=next(i2);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {

			    pr1_isMoreSpecific=true;
			    intersection->append(elem(i1));
			    i1=next(i1);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Equal)) {

			    return; 
			    	} else
			    kc_no_default_in_with( "compare_patterns", __LINE__, __FILE__ );
		    }

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PRStringLiteral) && (kc_selvar_0_2->prod_sel() == sel_PROperPredicate)) {
		    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_1)->path_1;
		    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_2)->path_1;

		    {
			tribool kc_selvar_1_1 = phylum_cast<tribool>(equal_path( a_path1, a_path2 ));
			if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {

			    pr2_isMoreSpecific=true;
			    intersection->append(elem(i2));
			    i2=next(i2);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {

			    pr1_isMoreSpecific=true;
			    intersection->append(elem(i1));
			    i1=next(i1);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Equal)) {

			    return; 
			    	} else
			    kc_no_default_in_with( "compare_patterns", __LINE__, __FILE__ );
		    }

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PRIntLiteral) && (kc_selvar_0_2->prod_sel() == sel_PRIntLiteral)) {
		    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_1)->path_1;
		    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRIntLiteral*>(kc_selvar_0_2)->path_1;

		    {
			tribool kc_selvar_1_1 = phylum_cast<tribool>(equal_path( a_path1, a_path2 ));
			if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {

			    pr2_isMoreSpecific=true;
			    intersection->append(elem(i2));
			    i2=next(i2);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {

			    pr1_isMoreSpecific=true;
			    intersection->append(elem(i1));
			    i1=next(i1);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Equal)) {

			    return; 
			    	} else
			    kc_no_default_in_with( "compare_patterns", __LINE__, __FILE__ );
		    }

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PRStringLiteral) && (kc_selvar_0_2->prod_sel() == sel_PRStringLiteral)) {
		    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_1)->path_1;
		    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PRStringLiteral*>(kc_selvar_0_2)->path_1;

		    {
			tribool kc_selvar_1_1 = phylum_cast<tribool>(equal_path( a_path1, a_path2 ));
			if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {

			    pr2_isMoreSpecific=true;
			    intersection->append(elem(i2));
			    i2=next(i2);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {

			    pr1_isMoreSpecific=true;
			    intersection->append(elem(i1));
			    i1=next(i1);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Equal)) {

			    return; 
			    	} else
			    kc_no_default_in_with( "compare_patterns", __LINE__, __FILE__ );
		    }

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PROperPredicate) && (kc_selvar_0_2->prod_sel() == sel_PROperPredicate)) {
		    const path a_path1 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_1)->path_1;
		    const path a_path2 = phylum_cast<const impl_elem_patternrepresentation_PROperPredicate*>(kc_selvar_0_2)->path_1;

		    {
			tribool kc_selvar_1_1 = phylum_cast<tribool>(equal_path( a_path1, a_path2 ));
			if ((kc_selvar_1_1->prod_sel() == sel_Bigger)) {

			    pr2_isMoreSpecific=true;
			    intersection->append(elem(i2));
			    i2=next(i2);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Smaller)) {

			    pr1_isMoreSpecific=true;
			    intersection->append(elem(i1));
			    i1=next(i1);

			} else
			    if ((kc_selvar_1_1->prod_sel() == sel_Equal)) {

			    return; 
			    	} else
			    kc_no_default_in_with( "compare_patterns", __LINE__, __FILE__ );
		    }

		} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PRWildcard)) {
		    return; 
		    	} else
		    if ((kc_selvar_0_1->prod_sel() == sel_PRDefault)) {
		    return; 
		    	} else
		    if ((kc_selvar_0_2->prod_sel() == sel_PRWildcard)) {
		    return; 
		    	} else
		    if ((kc_selvar_0_2->prod_sel() == sel_PRDefault)) {
		    return; 
		    	} else
		{

		    if(g_options.verbose) {
			printf("Don't know how to compare these yet:\n");
			printf("%s:%d ", epr1->file->name, epr1->line); elem(i1)->print();
			printf("%s:%d ", epr2->file->name, epr2->line); elem(i2)->print();
		    }
		    return;

		}
	    }
	}
    } 

    if (!(i1->is_nil() && i2->is_nil())) {
	patternrepresentation new_intersect;
	if (i1->is_nil()) {
	    new_intersect = concat(intersection, i2);
	    pr2_isMoreSpecific = true;
	} else {
	    new_intersect = concat(intersection, i1);
	    pr1_isMoreSpecific = true;
	}
	intersection->freelist();
	intersection=new_intersect;
    }

    if (!pr1_isMoreSpecific && !pr2_isMoreSpecific) {

	if (g_options.warn_equivalent_patterns) v_report(Warning(FileLine( epr1->file, epr1->line ),
		Problem3S1int1S("pattern equivalent to",
		    epr2->file->name, "line", epr2->line, "(will never match)") ));
    } else if (!pr1_isMoreSpecific || !pr2_isMoreSpecific) {

	return;
    } else {
	bool I_had_better = false;
	{
	    patternrepresentations kc_fe_selvar_1 =  other_patterns;

	    while(
		    kc_fe_selvar_1->prod_sel() == sel_Conspatternrepresentations
		) {
		patternrepresentation kc_selvar_0_1 = kc_fe_selvar_1->patternrepresentation_1;
		{
		    {
			{
			    const patternrepresentation pr = kc_selvar_0_1;

			    if (pr->eq(intersection))
			    I_had_better = true;

			}
		    }

		}
		kc_fe_selvar_1 = kc_fe_selvar_1->patternrepresentations_1;

	    }
	}
	if (!I_had_better && g_options.warn_overlapping_patterns)
	v_report(Warning(FileLine( epr1->file, epr1->line ),
		Problem3S1int1S("pattern overlaps",
		    epr2->file->name, "line", epr2->line, "(which will match?)") ));
    }

}


} // namespace kc
