6de9cd9a88
From-SVN: r81764
853 lines
18 KiB
C
853 lines
18 KiB
C
/*
|
|
* Copyright (c) 2000-2001
|
|
* The Regents of the University of California. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. Neither the name of the University nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#include "banshee.h"
|
|
#include "flowrow-sort.h"
|
|
#include "flowrow-var.h"
|
|
#include "setif-sort.h"
|
|
#include "setif-var.h"
|
|
#include "setst-sort.h"
|
|
#include "setst-var.h"
|
|
#include "term-sort.h"
|
|
#include "term-var.h"
|
|
|
|
struct constructor
|
|
{
|
|
sort_kind sort;
|
|
int type;
|
|
int arity;
|
|
char *name;
|
|
sig_elt *sig;
|
|
};
|
|
|
|
typedef struct constructor *constructor;
|
|
|
|
typedef enum
|
|
{
|
|
vnc_pos,
|
|
vnc_neg,
|
|
vnc_non
|
|
} vnc_kind;
|
|
|
|
struct sig_elt
|
|
{
|
|
vnc_kind variance;
|
|
sort_kind sort;
|
|
};
|
|
|
|
typedef struct sig_elt sig_elt;
|
|
|
|
typedef struct proj_pat
|
|
{
|
|
sort_kind sort;
|
|
int type;
|
|
stamp st;
|
|
int i;
|
|
gen_e exp;
|
|
vnc_kind variance;
|
|
constructor c;
|
|
} *proj_pat;
|
|
|
|
|
|
typedef struct cons_expr
|
|
{
|
|
sort_kind sort;
|
|
int type;
|
|
stamp st;
|
|
int arity;
|
|
char *name;
|
|
sig_elt *sig;
|
|
gen_e *exps;
|
|
} * cons_expr;
|
|
|
|
|
|
static int new_type()
|
|
{
|
|
static int type = 10;
|
|
int ret = type;
|
|
if (type > 2000)
|
|
{
|
|
fprintf(stderr, "Exceeded maximum number of constructors\n");
|
|
assert(0);
|
|
}
|
|
type += 2;
|
|
return ret;
|
|
}
|
|
|
|
static bool fixed_sort(sort_kind s)
|
|
{
|
|
return !(s == sort_term || s == sort_set);
|
|
}
|
|
|
|
/*
|
|
Convention : constructor types are even, pats are odd.
|
|
The smallest specialized type is 10.
|
|
*/
|
|
static bool setif_is_pat(gen_e e)
|
|
{
|
|
int type = ((setif_term)e)->type;
|
|
return ( (type & 1) && (type > 10) );
|
|
}
|
|
|
|
static bool setst_is_pat(gen_e e)
|
|
{
|
|
int type = ((setst_term)e)->type;
|
|
return ( (type & 1) && (type > 10) );
|
|
}
|
|
|
|
static gen_e get_proj_var(sort_kind s, bool large)
|
|
{
|
|
switch (s)
|
|
{
|
|
case setif_sort:
|
|
{
|
|
if (large)
|
|
return (gen_e)sv_fresh_large(get_sort_region(setif_sort),NULL);
|
|
else return (gen_e)sv_fresh(get_sort_region(setif_sort),NULL);
|
|
}
|
|
break;
|
|
case setst_sort:
|
|
{
|
|
if (large)
|
|
return (gen_e)st_fresh_large(get_sort_region(setst_sort),NULL);
|
|
else return (gen_e)st_fresh(get_sort_region(setst_sort),NULL);
|
|
}
|
|
break;
|
|
case flowrow_sort:
|
|
{
|
|
if (large)
|
|
return (gen_e)fv_fresh_large(get_sort_region(flowrow_sort),NULL);
|
|
else return (gen_e)fv_fresh(get_sort_region(flowrow_sort),NULL);
|
|
}
|
|
break;
|
|
case term_sort:
|
|
{
|
|
if (large)
|
|
return (gen_e)tv_fresh_large(get_sort_region(term_sort),NULL);
|
|
else return (gen_e)tv_fresh(get_sort_region(term_sort),NULL)
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
fail("Unmatched sort in get_proj_var\n");
|
|
return NULL;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static gen_e get_sort_zero(sort_kind s)
|
|
{
|
|
switch (s)
|
|
{
|
|
case setif_sort:
|
|
return setif_zero();
|
|
case setst_sort:
|
|
return setst_zero();
|
|
case flowrow_sort:
|
|
return flowrow_zero();
|
|
case term_sort:
|
|
return term_zero();
|
|
default:
|
|
fail("Unmatched sort in get_sort_zero\n");
|
|
return NULL;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static gen_e get_sort_one(sort_kind s)
|
|
{
|
|
switch (s)
|
|
{
|
|
case setif_sort:
|
|
return setif_one();
|
|
case setst_sort:
|
|
return setst_one();
|
|
case flowrow_sort:
|
|
return flowrow_one();
|
|
case term_sort:
|
|
return term_one();
|
|
default:
|
|
fail("Unmatched sort in get_sort_zero\n");
|
|
return NULL;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static region get_sort_region(sort s)
|
|
{
|
|
switch (s)
|
|
{
|
|
case setif_sort:
|
|
return setif_region;
|
|
case setst_sort:
|
|
return setst_region;
|
|
case flowrow_sort:
|
|
return flowrow_region;
|
|
case term_sort:
|
|
return term_region:
|
|
default:
|
|
fail("Unmatched sort in get_sort_region\n");
|
|
return NULL;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static term_hash get_sort_hash(sort s)
|
|
{
|
|
switch (s)
|
|
{
|
|
case setif_sort:
|
|
return setif_hash;
|
|
case setst_sort:
|
|
return setst_hash;
|
|
case flowrow_sort:
|
|
return flowrow_hash;
|
|
case term_sort:
|
|
return term_hash:
|
|
default:
|
|
fail("Unmatched sort in get_sort_hash\n");
|
|
return NULL;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
constructor make_constructor(const char *name,sort_kind sort, sig_elt s[],
|
|
int arity)
|
|
{
|
|
constructor c = ralloc(expr_region,struct constructor);
|
|
sig_elt *sig = rarrayalloc(expr_region,arity,sig_elt);
|
|
|
|
c->type = new_type();
|
|
|
|
if (arity)
|
|
{
|
|
memcpy(sig,s,sizeof(sig_elt)*arity);
|
|
}
|
|
|
|
if ( fixed_sort(sort) )
|
|
failure("Specified sort does not allow constructor types\n");
|
|
|
|
c->sort = sort;
|
|
c->arity = arity;
|
|
c->name = rstrdup(expr_region,name);
|
|
c->sig = sig;
|
|
|
|
return c;
|
|
}
|
|
|
|
gen_e constructor_expr(constructor c, gen_e exps[], int arity)
|
|
{
|
|
cons_expr result;
|
|
int i;
|
|
region sort_region = get_sort_region(c->sort);
|
|
term_hash sort_hash = get_sort_hash(c->sort);
|
|
|
|
stamp *st = rarrayalloc(sort_region,arity + 1,stamp);
|
|
st[0] = c->type;
|
|
|
|
// Dynamic arity check
|
|
if(arity != c->arity)
|
|
failure("Signature mismatch\n");
|
|
|
|
// Dynamic sort checks
|
|
for (i = 0; i < arity; i++)
|
|
{
|
|
if ( c->sig[i].sort != exps[i]->sort)
|
|
failure(stderr,"Signature mismatch\n");
|
|
st[i+1] = exps[i]->st;
|
|
}
|
|
|
|
// Hash-consing of terms
|
|
if (!(result = term_hash_find(sort_hash,st,arity+1)) || arity == 0 )
|
|
{
|
|
gen_e *e = rarrayalloc(sort_region,arity,gen_e);
|
|
|
|
if (arity)
|
|
memcpy(e,exps,sizeof(gen_e)*arity);
|
|
else
|
|
e = NULL;
|
|
|
|
result = ralloc(sort_region,struct cons_expr);
|
|
result->type = st[0];
|
|
result->st = stamp_fresh();
|
|
result->sort = c->sort;
|
|
result->arity = c->arity;
|
|
result->name = c->name;
|
|
result->sig = c->sig;
|
|
result->exps = e;
|
|
|
|
term_hash_insert(expr_hash,result,st,arity+1);
|
|
}
|
|
|
|
return (gen_e)result;
|
|
}
|
|
|
|
static gen_e proj_pat(constructor c, int i, gen_e e)
|
|
{
|
|
proj_pat pat;
|
|
region sort_region = get_sort_region(e->sort);
|
|
term_hash sort_hash = get_sort_hash(e->sort);
|
|
|
|
stamp s[3];
|
|
s[0] = c->type + 1;
|
|
s[1] = e->st;
|
|
s[2] = i;
|
|
|
|
if (! (pat = term_hash_find(sort_hash,s,3)) )
|
|
{
|
|
pat = ralloc(sort_region,struct proj_pat);
|
|
pat->type = s[0];
|
|
pat->st = stamp_fresh();
|
|
pat->sort = c->sort;
|
|
pat->exp = e;
|
|
pat->variance = c->sig[i].variance;
|
|
pat->c = c;
|
|
pat->i = i;
|
|
term_hash_insert(sort_hash,pat,s,3);
|
|
}
|
|
|
|
return (gen_e)pat;
|
|
}
|
|
|
|
gen_e setif_proj_pat(constructor c,int i,gen_e e)
|
|
{
|
|
return proj_pat(c,i,e);
|
|
}
|
|
|
|
gen_e setst_proj_pat(constructor c, int i, gen_e e)
|
|
{
|
|
return proj_pat(c,i,e);
|
|
}
|
|
|
|
gen_e setif_proj(constructor c, int i, gen_e e)
|
|
{
|
|
setif_var v;
|
|
gen_e proj_var, proj;
|
|
|
|
gen_e nonspec_get_proj(gen_e_list arg1)
|
|
{
|
|
proj_pat pat;
|
|
gen_e_list_scanner scan;
|
|
gen_e temp;
|
|
|
|
gen_e_list_scan(arg1,&scan);
|
|
while (gen_e_list_next(&scan,&temp))
|
|
{
|
|
pat = (proj_pat)temp;
|
|
if ( pat_match(pat->type,c->type) && i == pat->i )
|
|
return pat->exp;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
if (e->sort != setif_sort)
|
|
{
|
|
failure("Sort check : setif_proj\n");
|
|
}
|
|
|
|
else if (i < 0 || i > c->arity)
|
|
{
|
|
failure("Signature mismatch\n");
|
|
}
|
|
|
|
else if (setif_is_zero(e))
|
|
return get_sort_zero(c->sig[i].sort);
|
|
|
|
else if ( ((setif_term)e)->type == c->type )
|
|
{
|
|
cons_expr constructed = (cons_expr)e;
|
|
return constructed->exps[i];
|
|
}
|
|
|
|
else if (setif_is_var(e))
|
|
{
|
|
v = (setif_var)e;
|
|
if ( (proj = sv_get_ub_proj(v,nonspec_get_proj)) )
|
|
{
|
|
return proj;
|
|
}
|
|
else
|
|
{
|
|
gen_e pat;
|
|
gen_e_list_scanner scan;
|
|
gen_e lb;
|
|
proj_var = get_proj_var(c->sig[i].sort,FALSE);
|
|
pat = setif_proj_pat(c,i,proj_var);
|
|
sv_add_ub_proj(sort_region,v,pat);
|
|
|
|
gen_e_list_scan(sv_get_lbs(v),&scan);
|
|
while (gen_e_list_next(&scan,&lb))
|
|
{
|
|
setif_inclusion(lb,pat);
|
|
}
|
|
return proj_var;
|
|
}
|
|
}
|
|
|
|
else if (setif_is_union(e))
|
|
{
|
|
if( (proj = nonspec_get_proj(setif_get_proj_cache(e))) )
|
|
return proj;
|
|
else
|
|
{
|
|
gen_e pat;
|
|
proj_var = get_proj_var(c->sig[i].sort,FALSE);
|
|
pat = setif_proj_pat(c,i,proj_var);
|
|
|
|
setif_set_proj_cache(e,pat);
|
|
|
|
setif_inclusion(e,pat);
|
|
return proj_var;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gen_e pat;
|
|
proj_var = get_proj_var(c->sig[i].sort,FALSE);
|
|
pat = setif_proj_pat(c,i,proj_var);
|
|
setif_inclusion(e,pat);
|
|
return proj_var;
|
|
}
|
|
}
|
|
|
|
gen_e setst_proj(constructor c, int i, gen_e e)
|
|
{
|
|
setst_var v;
|
|
gen_e proj_var, proj;
|
|
|
|
gen_e nonspec_get_proj(gen_e_list arg1)
|
|
{
|
|
proj_pat pat;
|
|
gen_e_list_scanner scan;
|
|
gen_e temp;
|
|
|
|
gen_e_list_scan(arg1,&scan);
|
|
while (gen_e_list_next(&scan,&temp))
|
|
{
|
|
pat = (proj_pat)temp;
|
|
if ( pat_match(pat->type,c->type) && i == pat->i )
|
|
return pat->exp;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
if (e->sort != setst_sort)
|
|
{
|
|
failure("Sort check : setst_proj\n");
|
|
}
|
|
|
|
else if (i < 0 || i > c->arity)
|
|
{
|
|
failure("Signature mismatch\n");
|
|
}
|
|
|
|
else if (setst_is_zero(e))
|
|
return get_sort_zero(c->sig[i].sort);
|
|
|
|
else if ( ((setst_term)e)->type == c->type )
|
|
{
|
|
cons_expr constructed = (cons_expr)e;
|
|
return constructed->exps[i];
|
|
}
|
|
|
|
else if (setst_is_var(e))
|
|
{
|
|
v = (setst_var)e;
|
|
if ( (proj = sv_get_ub_proj(v,nonspec_get_proj)) )
|
|
{
|
|
return proj;
|
|
}
|
|
else
|
|
{
|
|
gen_e pat;
|
|
gen_e_list_scanner scan;
|
|
gen_e lb;
|
|
proj_var = get_proj_var(c->sig[i].sort,FALSE);
|
|
pat = setst_proj_pat(c,i,proj_var);
|
|
sv_add_ub_proj(sort_region,v,pat);
|
|
|
|
gen_e_list_scan(sv_get_lbs(v),&scan);
|
|
while (gen_e_list_next(&scan,&lb))
|
|
{
|
|
setst_inclusion(lb,pat);
|
|
}
|
|
return proj_var;
|
|
}
|
|
}
|
|
|
|
else if (setst_is_union(e))
|
|
{
|
|
if( (proj = nonspec_get_proj(setst_get_proj_cache(e))) )
|
|
return proj;
|
|
else
|
|
{
|
|
gen_e pat;
|
|
proj_var = get_proj_var(c->sig[i].sort,FALSE);
|
|
pat = setst_proj_pat(c,i,proj_var);
|
|
|
|
setst_set_proj_cache(e,pat);
|
|
|
|
setst_inclusion(e,pat);
|
|
return proj_var;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
gen_e pat;
|
|
proj_var = get_proj_var(c->sig[i].sort,FALSE);
|
|
pat = setst_proj_pat(c,i,proj_var);
|
|
setst_inclusion(e,pat);
|
|
return proj_var;
|
|
}
|
|
}
|
|
|
|
static void setif_con_match(gen_e e1, gen_e e2)
|
|
{
|
|
// Case where e1 is a constructor expression and e2 is a proj_pat
|
|
if (pat_match(((setif_term)e2)->type,((setif_term)e1)->type))
|
|
{
|
|
cons_expr c = (cons_expr)e1;
|
|
proj_pat p = (proj_pat)e2;
|
|
int i = p->i;
|
|
|
|
if (c->sig[i].variance == vnc_pos)
|
|
call_inclusion_fn(c->exps[i],p->exp);
|
|
else if (c->sig[i].variance == vnc_neg)
|
|
call_inclusion_fn(p->exp,c->exps[i]);
|
|
else
|
|
call_unify_fn(c->exps[i],p->exp);
|
|
}
|
|
else if (setif_is_pat(e2))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Case where e1 and e2 are constructor expressions
|
|
else
|
|
{
|
|
cons_expr c1 = (cons_expr)e1,
|
|
c2 = (cons_expr)e2;
|
|
|
|
if (c1->type != c2->type)
|
|
failure("Constructor mismatch\n");
|
|
else
|
|
{
|
|
int i;
|
|
for (i = 0; i < c1->arity; i++)
|
|
{
|
|
if (c1->sig[i].variance == vnc_pos)
|
|
call_inclusion_fn(e1,e2);
|
|
else if (c1->sig[i].variance == vnc_neg)
|
|
call_inclusion_fn(e2,e1);
|
|
else
|
|
call_unify_fn(e1,e2);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
static void setst_con_match(gen_e e1, gen_e e2)
|
|
{
|
|
// Case where e1 is a constructor expression and e2 is a proj_pat
|
|
if (pat_match(((setst_term)e2)->type,((setst_term)e1)->type))
|
|
{
|
|
cons_expr c = (cons_expr)e1;
|
|
proj_pat p = (proj_pat)e2;
|
|
int i = p->i;
|
|
|
|
if (c->sig[i].variance == vnc_pos)
|
|
call_inclusion_fn(c->exps[i],p->exp);
|
|
else if (c->sig[i].variance == vnc_neg)
|
|
call_inclusion_fn(p->exp,c->exps[i]);
|
|
else
|
|
call_unify_fn(c->exps[i],p->exp);
|
|
}
|
|
else if (setst_is_pat(e2))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Case where e1 and e2 are constructor expressions
|
|
else
|
|
{
|
|
cons_expr c1 = (cons_expr)e1,
|
|
c2 = (cons_expr)e2;
|
|
|
|
if (c1->type != c2->type)
|
|
failure("Constructor mismatch\n");
|
|
else
|
|
{
|
|
int i;
|
|
for (i = 0; i < c1->arity; i++)
|
|
{
|
|
if (c1->sig[i].variance == vnc_pos)
|
|
call_inclusion_fn(e1,e2);
|
|
else if (c1->sig[i].variance == vnc_neg)
|
|
call_inclusion_fn(e2,e1);
|
|
else
|
|
call_unify_fn(e1,e2);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// given x <= proj(c,i,e)
|
|
// proj_merge(region,e,get_proj_i_arg,fresh_large_fn_ptr,
|
|
// sort_inclusion_fn_ptr,set_inclusion)
|
|
static bool nonspec_res_proj(set_var v1,gen_e e2)
|
|
{
|
|
proj_pat projection_pat = (proj_pat)e2;
|
|
|
|
gen_e setif_get_proj(gen_e_list arg1)
|
|
{
|
|
gen_e_list_scanner scan;
|
|
gen_e temp;
|
|
proj_pat pat;
|
|
|
|
gen_e_list_scan(arg1,&scan);
|
|
while(gen_e_list_next(&scan,&temp))
|
|
{
|
|
pat = (proj_pat)temp;
|
|
if ( pat->type == ((setif_term)e2)->type &&
|
|
pat->i == ((proj_pat)e2)->i)
|
|
return pat->exp;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
gen_e fresh_large(void)
|
|
{
|
|
return get_proj_var( ((proj_pat)e2)->exp->sort,TRUE);
|
|
}
|
|
|
|
bool sort_inclusion(gen_e e1, gen_e e2)
|
|
{
|
|
if ( projection_pat->variance == vnc_pos )
|
|
return call_inclusion_fn(e1,e2);
|
|
else if ( projection_pat->variance == vnc_neg)
|
|
return call_inclusion_fn(e2,e1);
|
|
else
|
|
return call_unify_fn(e1,e2);
|
|
}
|
|
|
|
gen_e proj_con(gen_e e)
|
|
{
|
|
return make_proj_pat( ((proj_pat)e2)->c, ((proj_pat)e2)->i,e);
|
|
}
|
|
|
|
return setif_proj_merge(setif_region,v1,((proj_pat)e2)->exp,
|
|
setif_get_proj,proj_con,
|
|
fresh_large,sort_inclusion,
|
|
call_setif_inclusion);
|
|
|
|
}
|
|
|
|
|
|
void call_setif_inclusion(gen_e e1,gen_e e2)
|
|
{
|
|
setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
|
|
}
|
|
|
|
void call_setif_unify(gen_e e1, gen_e e2)
|
|
{
|
|
setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
|
|
setif_inclusion(setif_con_match,setif_res_proj,e2,e1);
|
|
}
|
|
|
|
void call_setst_inclusion(gen_e e1, gen_e e2)
|
|
{
|
|
setst_inclusion(setst_con_match,e1,e2);
|
|
}
|
|
|
|
void call_setst_unify(gen_e e1, gen_e e2)
|
|
{
|
|
setst_inclusion(setst_con_match,e1,e2);
|
|
setst_inclusion(setst_con_match,e2,e1);
|
|
}
|
|
|
|
void call_flowrow_inclusion(gen_e e1,gen_e e2)
|
|
{
|
|
|
|
if ( (e1->sort != flowrow_sort) || (e2->sort != flowrow_sort) )
|
|
failure("Constraint system is not well-sorted\n");
|
|
|
|
if ( flowrow_base_sort(e1) != flowrow_base_sert(e2))
|
|
failure("Constraint system is not well-sorted\n");
|
|
|
|
|
|
flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
|
|
}
|
|
|
|
void call_flowrow_unify(gen_e e1, gen_e e2)
|
|
{
|
|
flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
|
|
flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e2,e1);
|
|
}
|
|
|
|
static void term_con_match(gen_e e1, gen_e e2)
|
|
{
|
|
cons_expr c1 = (cons_expr)e1,
|
|
c2 = (cons_expr)e2;
|
|
|
|
if (c1->type != c2->type)
|
|
failure("Constructor mismatch\n");
|
|
else
|
|
{
|
|
int i;
|
|
for (i = 0; i < c1->arity; i++)
|
|
{
|
|
call_unify_fn(e1,e2);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
static void term_occurs(term_var v, gen_e e)
|
|
{
|
|
gen_e ecr = term_get_ecr(e);
|
|
|
|
if (((gen_term)ecr)->type == VAR_TYPE)
|
|
return ( term_get_stamp((gen_e)v) == term_get_stamp(e) );
|
|
|
|
else if (((gen_term)ecr)->type >= 10)
|
|
{
|
|
cons_expr c_e = (cons_expr) e;
|
|
int i;
|
|
for (int i = 0; i < arity; i++)
|
|
{
|
|
if (term_occurs(v,c->exps[i]))
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void call_term_unify(gen_e e1, gen_e e2)
|
|
{
|
|
term_unify(term_con_match,term_occurs,e1,e2);
|
|
}
|
|
|
|
void call_term_cunify(gen_e e1, gen_e e2)
|
|
{
|
|
term_cunify(term_con_match,term_occurs,e1,e2);
|
|
}
|
|
|
|
|
|
static void call_inclusion_fn(gen_e e1, gen_e e2)
|
|
{
|
|
switch (e1->sort)
|
|
{
|
|
case sort_setif:
|
|
{
|
|
setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
|
|
}
|
|
break;
|
|
case sort_setst:
|
|
{
|
|
setst_inclusion(setst_con_match,e1,e2);
|
|
}
|
|
break;
|
|
case sort_term:
|
|
{
|
|
term_unify(term_con_match,term_occurs,e1,e2);
|
|
}
|
|
break;
|
|
case sort_row:
|
|
{
|
|
/* TODO */
|
|
flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
|
|
}
|
|
break;
|
|
default :
|
|
fail("Unmatched sort in call inclusion\n");
|
|
}
|
|
}
|
|
|
|
static bool call_unify_fn(gen_e e1, gen_e e2)
|
|
{
|
|
|
|
switch (e1->sort)
|
|
{
|
|
case sort_setif:
|
|
{
|
|
setif_inclusion(setif_con_match,setif_res_proj,e1,e2);
|
|
setif_inclusion(setif_con_match,setif_res_proj,e2,e1);
|
|
}
|
|
break;
|
|
case sort_setst:
|
|
{
|
|
setst_inclusion(setst_con_match,e1,e2);
|
|
setst_inclusion(setst_con_match,e2,e1);
|
|
}
|
|
break;
|
|
case sort_term:
|
|
{
|
|
term_unify(term_con_match,term_occurs,e1,e2);
|
|
}
|
|
break;
|
|
case sort_row:
|
|
{
|
|
/* TODO */
|
|
flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e1,e2);
|
|
flowrow_inclusion(fresh,get_stamp,field_incl,zero_elem,e2,e1);
|
|
}
|
|
break;
|
|
default :
|
|
fail("Unmatched sort in call inclusion\n");
|
|
}
|
|
}
|
|
|
|
void nonspec_init(void)
|
|
{
|
|
banshee_init();
|
|
setif_init();
|
|
setst_init();
|
|
flowrow_init();
|
|
}
|
|
|
|
void nonspec_reset(void)
|
|
{
|
|
flowrow_reset();
|
|
setst_reset();
|
|
setif_reset();
|
|
banshee_reset();
|
|
}
|
|
|
|
void expr_print(FILE *f,gen_e e)
|
|
{
|
|
|
|
}
|