void eu065(char *ans) { int N = 99; mpz_t n, d, r; mpz_init(n); mpz_init(d); mpz_init(r); mpz_set_ui(n, eterm(N)); mpz_set_ui(d, 1); for (int i = N-1; i >= 0; i--) { mpz_swap(n, d); int t = eterm(i); mpz_addmul_ui(n, d, t); mpz_gcd(r, n, d); mpz_div(n, n, r); mpz_div(d, d, r); } sprintf(ans, "%d", digitsum(n)); mpz_clear(r); mpz_clear(d); mpz_clear(n); }
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 */
static void propagate_positive(int id, Mstate state) { Term t; #if 0 printf("propagage_positive: "); p_term(Cells[id].eterm); #endif for (t = Cells[id].occurrences; t != NULL; t = t->u.vp) { /* foreach term the rule applies to */ Term curr = t; Mclause clause_to_process; BOOL index_it; /* The following loop iterates up toward the root of the clause, rewriting terms. We stop when we get to a literal, an eterm that cannot be rewritten (we then index the eterm in this case), or when we get to a non-eterm. */ #if 0 printf("rewriting: "); p_mclause(containing_mclause(curr)); #endif while (!LITERAL(curr) && /* stop if literal */ !arith_op_term(curr) && /* stop if arithmetic term */ eterm(curr, &id) && /* stop if not eterm */ Cells[id].value != NULL) { /* stop if eterm not evaluable*/ Term result = Cells[id].value; Term parent = curr->container; int pos = arg_position(parent, curr); state->stack = update_and_push((void **) &(ARG(parent,pos)), result, state->stack); Mstats.rewrite_terms++; curr = parent; } /* while rewriting upward */ #if 0 printf("done: "); p_mclause(containing_mclause(curr)); #endif clause_to_process = NULL; /* set to possible new rule */ index_it = FALSE; /* should curr be indexed? */ if (arith_rel_term(curr) || arith_op_term(curr)) { Term parent_lit = containing_mliteral(curr); Mclause parent_clause = parent_lit->container; if (!parent_clause->subsumed) { BOOL evaluated; int b = arith_eval(parent_lit, &evaluated); if (evaluated) { Term result; if (b != 0 && b != 1) fatal_error("propagate_positive, arith_eval should be Boolean"); result = (b ? Domain[1] : Domain[0]); clause_to_process = handle_literal(parent_lit, result, state); } else if (EQ_TERM(curr)) clause_to_process = parent_clause; } } else if (!LITERAL(curr)) { /* curr is a term */ Term parent = curr->container; if (id != -1) index_it = TRUE; /* curr is a non-evaluable eterm */ /* If curr is 1 or 2 steps away from a literal, process it. */ if (LITERAL(parent)) clause_to_process = parent->container; else { parent = parent->container; if (LITERAL(parent)) clause_to_process = parent->container; } } else { /* curr is a literal (equality or nonquality, positive or negative) */ Mclause parent_clause = curr->container; if (!eterm(curr, &id)) /* non-eterm literal */ clause_to_process = parent_clause; else if (Cells[id].value == NULL) { /* non-evaluable eterm literal */ index_it = TRUE; clause_to_process = parent_clause; } else if (!parent_clause->subsumed) { clause_to_process = handle_literal(curr, Cells[id].value, state); } } /* literal */ if (index_it) { /* curr is an evaluable term or literal, e.g., f(1,2), but there is no rule for it. Therefore, we index it so that it can be found in case a rule appears later. */ Mstats.indexes++; state->stack = update_and_push((void **) &(curr->u.vp), Cells[id].occurrences, state->stack); state->stack = update_and_push((void **) &(Cells[id].occurrences), curr, state->stack); } if (clause_to_process != NULL) { process_clause(clause_to_process, state); if (!state->ok) return; } } /* foreach occurrence (container) of the cell just assigned */ } /* propagate_positive */