static void nterm_check_and_process(Term lit, Mstate state) { int pos; int id; int neg = NEGATED(lit); int eq = EQ_TERM(lit); int type = (neg && eq ? NEAR_ELIMINATION : NEAR_ASSIGNMENT); if (eq) { Term a0 = ARG(lit,0); Term a1 = ARG(lit,1); if (VARIABLE(a1) && nterm(a0, &pos, &id)) { insert_negprop_eq(lit, a0, VARNUM(a1), state); job_prepend(state, type, id, a0, a1, pos); } else if (VARIABLE(a0) && nterm(a1, &pos, &id)) { insert_negprop_eq(lit, a1, VARNUM(a0), state); job_prepend(state, type, id, a1, a0, pos); } } else if (nterm(lit, &pos, &id)) { insert_negprop_noneq(lit, state); job_prepend(state, NEAR_ASSIGNMENT, id, lit, (neg ? Domain[0] : Domain[1]), pos); } } /* nterm_check_and_process */
/* PUBLIC */ BOOL all_args_vars(Term t) { if (VARIABLE(t)) return TRUE; else { int i; for (i = 0; i < ARITY(t); i++) if (!VARIABLE(ARG(t,i))) return FALSE; return TRUE; } } /* all_args_vars */
static void process_clause(Mclause c, Mstate state) { if (c->subsumed) return; else if (c->u.active == 0) { if (flag(Opt->trace)) printf("\t\t\t\t\t** BACKUP **\n"); state->ok = FALSE; return; } else if (c->u.active != 1) return; /* nonunit, so do nothing */ else { /* OK, we have a nonsubsumed unit. */ Term lit, beta; BOOL negated, eq; int id; int i = 0; while (FALSE_TERM(LIT(c,i))) i++; lit = LIT(c,i); negated = NEGATED(lit); eq = EQ_TERM(lit); #if 0 printf("process_clause 1: "); p_matom(lit); #endif if (!eq && eterm(lit, &id)) beta = Domain[negated ? 0 : 1]; /* P(1,2,3) or ~P(1,2,3) */ else if (eq && eterm(ARG(lit,0),&id) && VARIABLE(ARG(lit,1))) beta = ARG(lit,1); /* f(1,2)=3 or f(1,2)!=3 */ else if (eq && eterm(ARG(lit,1),&id) && VARIABLE(ARG(lit,0))) beta = ARG(lit,0); /* 3=f(1,2) or 3!=f(1,2) */ else { if (flag(Opt->negprop)) /* If it is an nterm, index and insert into job list. */ nterm_check_and_process(lit, state); return; /* We cannot do anything else with the unit. */ } if (eq && negated) new_elimination(id, beta, state); /* f(1,2) != 3 */ else new_assignment(id, beta, state); /* f(1,2) = 3, P(0), ~P(0) */ } } /* process_clause */
/* PUBLIC */ BOOL same_structure(Term a, Term b) { if (VARIABLE(a) || VARIABLE(b)) return VARIABLE(a) && VARIABLE(b); else if (SYMNUM(a) != SYMNUM(b)) return FALSE; else { int i; for (i = 0; i < ARITY(a); i++) if (!same_structure(ARG(a,i), ARG(b,i))) return FALSE; return TRUE; } } /* same_structure */
/* PUBLIC */ int arith_evaluate(Term t, BOOL *evaluated) { if (!arith_term(t)) { *evaluated = FALSE; return 0; } if (VARIABLE(t)) return VARNUM(t); else { int sn = SYMNUM(t); if (sn == Div_sn || sn == Mod_sn) { int d = arith_evaluate(ARG(t,1), evaluated); if (d == 0) { *evaluated = FALSE; return 0; } else if (sn == Div_sn) return arith_evaluate(ARG(t,0), evaluated) / d; else return modulo(arith_evaluate(ARG(t,0), evaluated), d); } else if (sn == Sum_sn) return arith_evaluate(ARG(t,0), evaluated) + arith_evaluate(ARG(t,1), evaluated); else if (sn == Prod_sn) return arith_evaluate(ARG(t,0), evaluated) * arith_evaluate(ARG(t,1), evaluated); else if (sn == Neg_sn) return -arith_evaluate(ARG(t,0), evaluated); else if (sn == Abs_sn) return abs(arith_evaluate(ARG(t,0), evaluated)); else if (sn == Domain_size_sn) return Domain_size; else if (sn == Min_sn) { int a0 = arith_evaluate(ARG(t,0), evaluated); int a1 = arith_evaluate(ARG(t,1), evaluated); return IMIN(a0,a1); } else if (sn == Max_sn) { int a0 = arith_evaluate(ARG(t,0), evaluated); int a1 = arith_evaluate(ARG(t,1), evaluated); return IMAX(a0,a1); } else if (sn == Lt_sn) return arith_evaluate(ARG(t,0), evaluated) < arith_evaluate(ARG(t,1), evaluated); else if (sn == Le_sn) return arith_evaluate(ARG(t,0), evaluated) <= arith_evaluate(ARG(t,1), evaluated); else if (sn == Gt_sn) return arith_evaluate(ARG(t,0), evaluated) > arith_evaluate(ARG(t,1), evaluated); else if (sn == Ge_sn) return arith_evaluate(ARG(t,0), evaluated) >= arith_evaluate(ARG(t,1), evaluated); else if (sn == Eq_sn) return arith_evaluate(ARG(t,0), evaluated) == arith_evaluate(ARG(t,1), evaluated); else { fatal_error("arith_evaluate, operation not handled"); return INT_MIN; } } } /* arith_evaluate */
/* PUBLIC */ BOOL arith_term(Term t) { if (VARIABLE(t)) return TRUE; else return arith_op_term(t) || arith_rel_term(t); } /* arith_term */
void traductionReglesU (Sudoku S, FILE *f){ int cpt2, i; // if (S.Nsymbol <= 9){ for (int cpt = 0 ; cpt < S.RU.nbU ; cpt ++){ i = 0; while ((i < N) && (S.RU.U[cpt][i].x != -1)){ for (int k = 1 ; k <= S.Nsymbol ; k++){ cpt2 = i + 1; while ((cpt2 < N) && (S.RU.U[cpt][cpt2].x != -1)){ fprintf(f, "-%d -%d 0\n",VARIABLE(S.RU.U[cpt][i].x, S.RU.U[cpt][i].y, k, S.Nsymbol), VARIABLE(S.RU.U[cpt][cpt2].x, S.RU.U[cpt][cpt2].y, k, S.Nsymbol)); cpt2++; } } i++; } } //} // gérer les sudoku classiques 16*16 /*else{ for (int cpt = 0 ; cpt < S.RU.nbU ; cpt ++){ for (int k = 1 ; k <= S.Nsymbol ; k++){ cpt2 = 0; while ((cpt2 < N) && (S.RU.U[cpt][cpt2].x != -1)){ fprintf(f, "%d ", VARIABLE(S.RU.U[cpt][cpt2].x, S.RU.U[cpt][cpt2].y, k, S.Nsymbol)); cpt2++; } fprintf(f, "0\n"); } } }*/ }
static Term vars_to_names(Term t) { if (VARIABLE(t)) { Term a; char *s1 = malloc(25); char *s2 = malloc(25); Variable_style v = variable_style(); s2 = int_to_str(VARNUM(t), s2, 25); switch (v) { case INTEGER_STYLE: s1 = strcpy(s1, ""); break; case STANDARD_STYLE: s1 = strcpy(s1, "var_"); break; case PROLOG_STYLE: s1 = strcpy(s1, "VAR_"); break; } s1 = strcat(s1, s2); a = get_rigid_term(s1, 0); free_term(t); free(s1); free(s2); return a; } else { int i; for (i = 0; i < ARITY(t); i++) ARG(t,i) = vars_to_names(ARG(t,i)); return t; } } /* vars_to_names */
/* PUBLIC */ void sprint_term(String_buf sb, Term t) { if (t == NULL) printf("sprint_term: NULL term\n"); else { if (VARIABLE(t)) { char s[MAX_NAME]; sprintf(s, "v%d", VARNUM(t)); sb_append(sb, s); } else { sprint_sym(sb, SYMNUM(t)); if (COMPLEX(t)) { int i; sb_append(sb, "("); for (i = 0; i < ARITY(t); i++) { sprint_term(sb, ARG(t,i)); if (i < ARITY(t)-1) sb_append(sb, ","); } sb_append(sb, ")"); } } } } /* sprint_term */
/* PUBLIC */ void free_term(Term p) { if (VARIABLE(p)) return; /* variables are never freed, because they are shared */ Arg_mem -= p->arity; free_mem(p, PTRS_TERM + p->arity); Term_frees++; } /* free_term */
static Term qsimp(Term t) { if (VARIABLE(t)) return t; else { int i; BOOL all_args_ints = TRUE; for (i = 0; i < ARITY(t); i++) { ARG(t,i) = qsimp(ARG(t,i)); if (!(VARIABLE(ARG(t,i)) || (SYMNUM(ARG(t,i)) == Neg_sn && VARIABLE(ARG(ARG(t,i),0))))) all_args_ints = FALSE; } if (all_args_ints) { BOOL evaluated; int i = arith_eval(t, &evaluated); if (evaluated) { zap_term(t); if (i >= 0) return get_variable_term(i); else return build_unary_term(Neg_sn, get_variable_term(-i)); } else return t; } else { if (SYMNUM(t) != Prod_sn && VARIABLE(ARG(t,0)) && VARNUM(ARG(t,0)) == 0) { /* 0*x to 0 */ zap_term(t); return get_variable_term(0); } else if (SYMNUM(t) != Sum_sn && SYMNUM(ARG(t,1)) == Neg_sn && term_ident(ARG(t,0),ARG(ARG(t,1),0))) { /* x + -x to 0 */ zap_term(t); return get_variable_term(0); } else return t; } } } /* qsimp */
/* PUBLIC */ void upward_term_links(Term t, void *p) { int i; if (!VARIABLE(t)) { t->container = p; for (i = 0; i < ARITY(t); i++) upward_term_links(ARG(t,i), p); } } /* upward_term_links */
/* PUBLIC */ I2list symbols_in_term(Term t, I2list g) { if (!VARIABLE(t)) { int i; g = multiset_add(g, SYMNUM(t)); for (i = 0; i < ARITY(t); i++) g = symbols_in_term(ARG(t,i), g); } return g; } /* symbols_in_term */
BOOL eterm(Term t, int *pid) { *pid = -1; /* We must return -1 if the term is not evaluable. */ if (t == NULL || VARIABLE(t) || arith_rel_term(t) || arith_op_term(t)) return FALSE; else { int i; int mult = 1; int id = Sn_to_mace_sn[SYMNUM(t)]->base; for (i = ARITY(t)-1; i >= 0; i--) { if (!VARIABLE(ARG(t,i))) return FALSE; else id += VARNUM(ARG(t,i)) * mult; mult *= Domain_size; } *pid = id; return TRUE; } } /* eterm */
/* PUBLIC */ I2list multiset_of_vars(Term t, I2list vars) { if (VARIABLE(t)) return multiset_add(vars, VARNUM(t)); else { int i; for (i = 0; i < ARITY(t); i++) vars = multiset_of_vars(ARG(t,i), vars); return vars; } } /* multiset_of_vars */
/* PUBLIC */ BOOL ground_term(Term t) { if (VARIABLE(t)) return FALSE; else { int i; for (i = 0; i < ARITY(t); i++) if (!ground_term(ARG(t,i))) return FALSE; return TRUE; } } /* ground_term */
/* PUBLIC */ unsigned hash_term(Term t) { if (VARIABLE(t)) return VARNUM(t); else { int i; unsigned x = SYMNUM(t); for (i = 0; i < ARITY(t); i++) x = (x << 3) ^ hash_term(ARG(t,i)); return x; } } /* hash_term */
static BOOL top_safe(Term t, int domain_size) { if (VARIABLE(t)) return TRUE; else if (CONSTANT(t)) return natural_constant_term(t) < domain_size; else if (arith_op_term(t) || arith_rel_term(t)) return FALSE; else return TRUE; } /* top_safe */
/* PUBLIC */ int symbol_occurrences(Term t, int symnum) { if (VARIABLE(t)) return 0; else { int n = (SYMNUM(t) == symnum ? 1 : 0); int i; for (i = 0; i < ARITY(t); i++) n += symbol_occurrences(ARG(t,i), symnum); return n; } } /* symbol_occurrences */
static BOOL non_arith(Term t) { if (VARIABLE(t)) return FALSE; else if (CONSTANT(t)) return natural_constant_term(t) < 0; else if (arith_rel_term(t) || arith_op_term(t)) return FALSE; else return TRUE; } /* non_arith */
/* PUBLIC */ BOOL args_distinct_vars(Term t) { #if 1 if (VARIABLE(t)) return FALSE; else { int i; for (i = 0; i < ARITY(t); i++) { if (!VARIABLE(ARG(t,i))) return FALSE; else { int j; for (j = 0; j < i; j++) if (VARNUM(ARG(t,i)) == VARNUM(ARG(t,j))) return FALSE; } } return TRUE; } #else if (VARIABLE(t)) return FALSE; else { int *p = calloc(ARITY(t), sizeof(int)); int i; BOOL ok = TRUE; for (i = 0; i < ARITY(t) && ok; i++) { Term s = ARG(t,i); if (!VARIABLE(s)) ok = FALSE; else if (p[VARNUM(s)]) ok = FALSE; else p[VARNUM(s)] = TRUE; } free(p); return ok; } #endif } /* args_distinct_vars */
void remplissageClassique (Sudoku S, FILE *f){ // Valeur unique dans chaque cellule. for (int i = 0; i < S.Nrows; i++){ for (int j = 0; j < S.Ncolumns; j++){ for (int k = 1; k <= S.Nsymbol; k++) fprintf(f, "%d ", VARIABLE(i, j, k, S.Nsymbol)); fprintf(f, "0\n"); } } // Une seule valeur par cellule for (int i = 0; i < S.Nrows; i++){ for (int j = 0; j < S.Ncolumns; j++){ for (int k1 = 1; k1 <= S.Nsymbol; k1++){ for (int k2 = 1; k2 < k1; k2++) fprintf(f, "-%d -%d 0\n", VARIABLE(i, j, k1, S.Nsymbol), VARIABLE(i, j, k2, S.Nsymbol)); } } } }
/* PUBLIC */ BOOL check_upward_term_links(Term t, void *p) { int i; if (!VARIABLE(t)) { if (t->container != p) return FALSE; for (i = 0; i < ARITY(t); i++) { if (!check_upward_term_links(ARG(t,i), p)) return FALSE; } } return TRUE; } /* check_upward_term_links */
/* PUBLIC */ int greatest_variable(Term t) { if (VARIABLE(t)) return VARNUM(t); else { int i, max, v; for (max = -1, i = 0; i < ARITY(t); i++) { v = greatest_variable(ARG(t,i)); max = (v > max ? v : max); } return max; } } /* greatest_variable */
/* PUBLIC */ int greatest_symnum_in_term(Term t) { if (VARIABLE(t)) return -1; else { int max = SYMNUM(t); int i; for (i = 0; i < ARITY(t); i++) { int sm = greatest_symnum_in_term(ARG(t,i)); max = (sm > max ? sm : max); } return max; } } /* greatest_symnum_in_term */
/* PUBLIC */ BOOL contains_skolem_term(Term t) { if (VARIABLE(t)) return FALSE; else if (skolem_term(t)) return TRUE; else { int i; for (i = 0; i < ARITY(t); i++) if (contains_skolem_term(ARG(t,i))) return TRUE; return FALSE; } } /* contains_skolem_term */
/* PUBLIC */ BOOL contains_skolem_function(Term t) { if (VARIABLE(t)) return FALSE; else if (COMPLEX(t) && skolem_term(t)) return TRUE; else { int i; for (i = 0; i < ARITY(t); i++) if (contains_skolem_function(ARG(t,i))) return TRUE; return FALSE; } } /* contains_skolem_function */
/* PUBLIC */ int term_depth(Term t) { if (VARIABLE(t) || CONSTANT(t)) return 0; else { int i; int max = 0; for (i = 0; i < ARITY(t); i++) { int d = term_depth(ARG(t,i)); max = IMAX(max,d); } return max+1; } } /* term_depth */
/* PUBLIC */ BOOL symbol_in_term(int symnum, Term t) { if (VARIABLE(t)) return FALSE; else if (SYMNUM(t) == symnum) return TRUE; else { int i; for (i = 0; i < ARITY(t); i++) if (symbol_in_term(symnum, ARG(t,i))) return TRUE; return FALSE; } } /* symbol_in_term */
/* PUBLIC */ Term copy_term(Term t) { if (t == NULL) return NULL; else if (VARIABLE(t)) return get_variable_term(VARNUM(t)); else { int i; Term t2 = get_rigid_term_like(t); for (i = 0; i < ARITY(t); i++) ARG(t2,i) = copy_term(ARG(t,i)); return t2; } } /* copy_term */