/*  Generated by CHR bootstrap compiler
    From: /tmp/pkgbuild/lang/swi-prolog-lite/work.sparc64/swipl-8.0.2/packages/chr/chr_translate_bootstrap2.chr
    Date: Fri Jan 15 12:31:52 2021

    DO NOT EDIT.  EDIT THE CHR FILE INSTEAD
*/

:- module(chr_translate,
          [ chr_translate/2
          ]).
:- use_module(chr(chr_runtime)).
:- style_check(- (discontiguous)).
:- style_check(-singleton).
:- style_check(-no_effect).
:- use_module(chr(chr_runtime)).
:- use_module(chr(chr_hashtable_store)).
:- style_check(- (discontiguous)).
:- use_module(library(lists),
              [ append/3,
                member/2,
                delete/3,
                reverse/2,
                permutation/2
              ]).
:- use_module(library(ordsets)).
:- use_module(library(dialect/hprolog)).
:- use_module(chr(pairlist)).
:- use_module(chr(a_star)).
:- use_module(chr(clean_code)).
:- use_module(chr(builtins)).
:- use_module(chr(find)).
:- include(chr(chr_op2)).
chr_translate(A, D) :-
    init_chr_pp_flags,
    partition_clauses(A, B, E, C),
    (   B==[]
    ->  insert_declarations(C, D)
    ;   add_rules(E),
        check_rules(E, B),
        add_occurrences(E),
        late_allocation(B),
        unique_analyse_optimise(E, F),
        check_attachments(B),
        assume_constraint_stores(B),
        set_constraint_indices(B, 1),
        constraints_code(B, F, I),
        validate_store_type_assumptions(B),
        store_management_preds(B, H),
        insert_declarations(C, G),
        chr_module_declaration(J),
        append([G, H, I, J], D)
    ).
store_management_preds(A, I) :-
    generate_attach_detach_a_constraint_all(A, B),
    generate_indexed_variables_clauses(A, C),
    generate_attach_increment(D),
    generate_attr_unify_hook(E),
    generate_extra_clauses(A, F),
    generate_insert_delete_constraints(A, G),
    generate_store_code(A, H),
    append([B, C, D, E, F, G, H], I).
specific_declarations([(:-use_module(chr(chr_runtime))),  (:-use_module(chr(chr_hashtable_store))),  (:-style_check(- (discontiguous)))|A], A).
insert_declarations(A, B) :-
    specific_declarations(E, F),
    (   A=[(:-module(C, D))|G]
    ->  B=[(:-module(C, D))|E],
        F=G
    ;   B=E,
        F=A
    ).
chr_module_declaration(B) :-
    get_target_module(A),
    (   A\==chr_translate
    ->  B=[(:-multifile chr:'$chr_module'/1), chr:'$chr_module'(A)]
    ;   B=[]
    ).
partition_clauses([], [], [], []).
partition_clauses([A|M], B, C, E) :-
    (   parse_rule(A, D)
    ->  B=G,
        C=[D|H],
        E=I
    ;   is_declaration(A, F)
    ->  append(F, G, B),
        C=H,
        E=I
    ;   is_module_declaration(A, J)
    ->  target_module(J),
        B=G,
        C=H,
        E=[A|I]
    ;   A=handler(_)
    ->  format('CHR compiler WARNING: ~w.\n', [A]),
        format('    `-->  SICStus compatibility: ignoring handler/1 declaration.\n',
               []),
        B=G,
        C=H,
        E=I
    ;   A=rules(_)
    ->  format('CHR compiler WARNING: ~w.\n', [A]),
        format('    `-->  SICStus compatibility: ignoring rules/1 declaration.\n',
               []),
        B=G,
        C=H,
        E=I
    ;   A=(:-chr_option(K, L))
    ->  handle_option(K, L),
        B=G,
        C=H,
        E=I
    ;   A=(:-chr_type(_))
    ->  B=G,
        C=H,
        E=I
    ;   B=G,
        C=H,
        E=[A|I]
    ),
    partition_clauses(M, G, H, I).
is_declaration(A, D) :-
    A=(:-B),
    (   B=..[chr_constraint, C]
    ;   B=..[chr_constraint, C]
    ),
    conj2list(C, D).
parse_rule(A, D) :-
    A= @(C, B),
    !,
    rule(B, yes(C), D).
parse_rule(A, B) :-
    rule(A, no, B).
rule(A, H, D) :-
    A=pragma(B, C),
    !,
    is_rule(B, E, F),
    conj2list(C, G),
    inc_rule_count(I),
    D=pragma(E, F, G, H, I).
rule(A, E, B) :-
    is_rule(A, C, D),
    inc_rule_count(F),
    B=pragma(C, D, [], E, F).
is_rule(A, G, D) :-
    A= ==>(B, F),
    !,
    conj2list(B, C),
    get_ids(C, E, H),
    D=ids([], E),
    (   F=(I| J)
    ->  G=rule([], H, I, J)
    ;   G=rule([], H, true, F)
    ).
is_rule(A, R, M) :-
    A= <=>(G, B),
    !,
    (   B=(C| D)
    ->  E=C,
        F=D
    ;   E=true,
        F=B
    ),
    (   G= \(H, I)
    ->  conj2list(H, J),
        conj2list(I, K),
        get_ids(J, O, P, 0, L),
        get_ids(K, N, Q, L, _),
        M=ids(N, O)
    ;   conj2list(G, K),
        P=[],
        get_ids(K, N, Q),
        M=ids(N, [])
    ),
    R=rule(Q, P, E, F).
get_ids(A, B, C) :-
    get_ids(A, B, C, 0, _).
get_ids([], [], [], A, A).
get_ids([B|D], [A|E], [C|F], A, H) :-
    (   B= #(C, A)
    ->  true
    ;   C=B
    ),
    G is A+1,
    get_ids(D, E, F, G, H).
is_module_declaration((:-module(A)), A).
is_module_declaration((:-module(A, _)), A).
add_rules([]).
add_rules([A|C]) :-
    A=pragma(_, _, _, _, B),
    rule(B, A),
    add_rules(C).
check_rules([], _).
check_rules([A|C], B) :-
    check_rule(A, B),
    check_rules(C, B).
check_rule(A, F) :-
    check_rule_indexing(A),
    A=pragma(B, _, G, _, _),
    B=rule(C, D, _, _),
    append(C, D, E),
    check_head_constraints(E, F, A),
    check_pragmas(G, A).
check_head_constraints([], _, _).
check_head_constraints([A|E], D, F) :-
    functor(A, B, C),
    (   member(B/C, D)
    ->  check_head_constraints(E, D, F)
    ;   format('CHR compiler ERROR: Undeclared constraint ~w in head of ~@.\n',
               [B/C, format_rule(F)]),
        format('    `--> Constraint should be one of ~w.\n', [D]),
        fail
    ).
check_pragmas([], _).
check_pragmas([A|C], B) :-
    check_pragma(A, B),
    check_pragmas(C, B).
check_pragma(A, B) :-
    var(A),
    !,
    format('CHR compiler ERROR: invalid pragma ~w in ~@.\n',
           [A, format_rule(B)]),
    format('    `--> Pragma should not be a variable!\n', []),
    fail.
check_pragma(passive(B), A) :-
    !,
    A=pragma(_, ids(C, D), _, _, E),
    (   memberchk_eq(B, C)
    ->  true
    ;   memberchk_eq(B, D)
    ->  true
    ;   format('CHR compiler ERROR: invalid identifier ~w in pragma passive in ~@.\n',
               [B, format_rule(A)]),
        fail
    ),
    passive(E, B).
check_pragma(A, B) :-
    A=unique(D, E),
    !,
    B=pragma(_, _, _, _, C),
    pragma_unique(C, D, E),
    format('CHR compiler WARNING: undocumented pragma ~w in ~@.\n',
           [A, format_rule(B)]),
    format('    `--> Only use this pragma if you know what you are doing.\n', []).
check_pragma(A, B) :-
    A=already_in_heads,
    !,
    format('CHR compiler WARNING: currently unsupported pragma ~w in ~@.\n',
           [A, format_rule(B)]),
    format('    `--> Pragma is ignored. Termination and correctness may be affected \n',
           []).
check_pragma(A, B) :-
    A=already_in_head(_),
    !,
    format('CHR compiler WARNING: currently unsupported pragma ~w in ~@.\n',
           [A, format_rule(B)]),
    format('    `--> Pragma is ignored. Termination and correctness may be affected \n',
           []).
check_pragma(A, B) :-
    format('CHR compiler ERROR: invalid pragma ~w in ~@.\n',
           [A, format_rule(B)]),
    format('    `--> Pragma should be one of passive/1!\n', []),
    fail.
format_rule(A) :-
    A=pragma(_, _, _, B, D),
    (   B=yes(C)
    ->  write('rule '),
        write(C)
    ;   write('rule number '),
        write(D)
    ).
check_rule_indexing(A) :-
    A=pragma(B, _, _, _, _),
    B=rule(C, D, E, _),
    term_variables(C-D, F),
    remove_anti_monotonic_guards(E, F, G),
    check_indexing(C, G-D),
    check_indexing(D, G-C).
remove_anti_monotonic_guards(A, C, E) :-
    conj2list(A, B),
    remove_anti_monotonic_guard_list(B, C, D),
    list2conj(D, E).
remove_anti_monotonic_guard_list([], _, []).
remove_anti_monotonic_guard_list([A|F], C, D) :-
    (   A=var(B),
        memberchk_eq(B, C)
    ->  D=E
    ;   D=[A|E]
    ),
    remove_anti_monotonic_guard_list(F, C, E).
check_indexing([], _).
check_indexing([A|B], C) :-
    functor(A, E, F),
    A=..[_|D],
    term_variables(B-C, G),
    check_indexing(D, 1, E/F, G),
    check_indexing(B, [A|C]).
check_indexing([], _, _, _).
check_indexing([C|D], B, A, F) :-
    (   is_indexed_argument(A, B)
    ->  true
    ;   nonvar(C)
    ->  indexed_argument(A, B)
    ;   term_variables(D, E),
        append(E, F, G),
        (   memberchk_eq(C, G)
        ->  indexed_argument(A, B)
        ;   true
        )
    ),
    I is B+1,
    term_variables(C, H),
    append(H, F, J),
    check_indexing(D, I, A, J).
add_occurrences([]).
add_occurrences([A|G]) :-
    A=pragma(rule(B, E, _, _), ids(C, F), _, _, D),
    add_occurrences(B, C, D),
    add_occurrences(E, F, D),
    add_occurrences(G).
add_occurrences([], [], _).
add_occurrences([A|I], [H|J], G) :-
    functor(A, B, C),
    D=B/C,
    get_max_occurrence(D, E),
    F is E+1,
    occurrence(D, F, G, H),
    add_occurrences(I, J, G).
late_allocation([]).
late_allocation([A|B]) :-
    allocation_occurrence(A, 1),
    late_allocation(B).
handle_option(A, B) :-
    var(A),
    !,
    format('CHR compiler ERROR: ~w.\n', [option(A, B)]),
    format('    `--> First argument should be an atom, not a variable.\n', []),
    fail.
handle_option(B, A) :-
    var(A),
    !,
    format('CHR compiler ERROR: ~w.\n', [option(B, A)]),
    format('    `--> Second argument should be a nonvariable.\n', []),
    fail.
handle_option(A, B) :-
    option_definition(A, B, C),
    !,
    set_chr_pp_flags(C).
handle_option(A, B) :-
    \+ option_definition(A, _, _),
    !,
    format('CHR compiler WARNING: ~w.\n', [option(A, B)]),
    format('    `--> Invalid option name \n', []).
handle_option(A, C) :-
    findall(B, option_definition(A, B, _), D),
    format('CHR compiler ERROR: ~w.\n', [option(A, C)]),
    format('    `--> Invalid value ~w: should be one of ~w.\n', [C, D]),
    fail.
option_definition(optimize, experimental, A) :-
    A=[unique_analyse_optimise-on, check_unnecessary_active-full, reorder_heads-on, set_semantics_rule-on, check_attachments-on, guard_via_reschedule-on].
option_definition(optimize, full, A) :-
    A=[unique_analyse_optimise-off, check_unnecessary_active-full, reorder_heads-on, set_semantics_rule-on, check_attachments-on, guard_via_reschedule-on].
option_definition(optimize, sicstus, A) :-
    A=[unique_analyse_optimise-off, check_unnecessary_active-simplification, reorder_heads-off, set_semantics_rule-off, check_attachments-off, guard_via_reschedule-off].
option_definition(optimize, off, A) :-
    A=[unique_analyse_optimise-off, check_unnecessary_active-off, reorder_heads-off, set_semantics_rule-off, check_attachments-off, guard_via_reschedule-off].
option_definition(check_guard_bindings, on, A) :-
    A=[guard_locks-on].
option_definition(check_guard_bindings, off, A) :-
    A=[guard_locks-off].
option_definition(reduced_indexing, on, A) :-
    A=[reduced_indexing-on].
option_definition(reduced_indexing, off, A) :-
    A=[reduced_indexing-off].
option_definition(mode, A, []) :-
    (   nonvar(A)
    ->  functor(A, B, C),
        A=..[_|D],
        constraint_mode(B/C, D)
    ;   true
    ).
option_definition(store, A-B, []) :-
    store_type(A, B).
option_definition(debug, on, A) :-
    A=[debugable-on].
option_definition(debug, off, A) :-
    A=[debugable-off].
option_definition(type_definition, _, []).
option_definition(type_declaration, _, []).
option_definition(verbosity, _, []).
init_chr_pp_flags :-
    chr_pp_flag_definition(A, [B|_]),
    set_chr_pp_flag(A, B),
    fail.
init_chr_pp_flags.
set_chr_pp_flags([]).
set_chr_pp_flags([A-B|C]) :-
    set_chr_pp_flag(A, B),
    set_chr_pp_flags(C).
set_chr_pp_flag(A, C) :-
    atom_concat('$chr_pp_', A, B),
    nb_setval(B, C).
chr_pp_flag_definition(unique_analyse_optimise, [on, off]).
chr_pp_flag_definition(check_unnecessary_active, [full, simplification, off]).
chr_pp_flag_definition(reorder_heads, [on, off]).
chr_pp_flag_definition(set_semantics_rule, [on, off]).
chr_pp_flag_definition(guard_via_reschedule, [on, off]).
chr_pp_flag_definition(guard_locks, [on, off]).
chr_pp_flag_definition(check_attachments, [on, off]).
chr_pp_flag_definition(debugable, [off, on]).
chr_pp_flag_definition(reduced_indexing, [on, off]).
chr_pp_flag(A, D) :-
    atom_concat('$chr_pp_', A, B),
    nb_getval(B, C),
    (   C==[]
    ->  chr_pp_flag_definition(A, [D|_])
    ;   C=D
    ).
generate_attach_detach_a_constraint_all([], []).
generate_attach_detach_a_constraint_all([A|D], F) :-
    (   may_trigger(A)
    ->  generate_attach_a_constraint(A, B),
        generate_detach_a_constraint(A, C)
    ;   B=[],
        C=[]
    ),
    generate_attach_detach_a_constraint_all(D, E),
    append([B, C, E], F).
generate_attach_a_constraint(A, [B, D]) :-
    generate_attach_a_constraint_empty_list(A, B),
    get_max_constraint_index(C),
    (   C==1
    ->  generate_attach_a_constraint_1_1(A, D)
    ;   generate_attach_a_constraint_t_p(A, D)
    ).
generate_attach_a_constraint_skeleton(A, C, F, D) :-
    make_name(attach_, A, B),
    E=..[B|C],
    D=(E:-F).
generate_attach_a_constraint_empty_list(A, B) :-
    generate_attach_a_constraint_skeleton(A, [[], _], true, B).
generate_attach_a_constraint_1_1(A, C) :-
    B=[[D|G], E],
    generate_attach_a_constraint_skeleton(A, B, H, C),
    generate_attach_body_1(A, D, E, I),
    make_name(attach_, A, F),
    J=..[F, G, E],
    H=(I, J).
generate_attach_body_1(_, B, D, A) :-
    get_target_module(C),
    A=(get_attr(B, C, E)->F=[D|E], put_attr(B, C, F);put_attr(B, C, [D])).
generate_attach_a_constraint_t_p(A, C) :-
    B=[[G|E], F],
    generate_attach_a_constraint_skeleton(A, B, H, C),
    make_name(attach_, A, D),
    J=..[D, E, F],
    generate_attach_body_n(A, G, F, I),
    H=(I, J).
generate_attach_body_n(A/B, O, G, N) :-
    get_constraint_index(A/B, C),
    or_pattern(C, M),
    get_max_constraint_index(D),
    make_attr(D, H, E, R),
    nth1(C, E, F),
    substitute_eq(F, E, [G|F], I),
    make_attr(D, H, I, S),
    substitute_eq(F, E, [G], J),
    make_attr(D, T, J, U),
    copy_term_nat(E, K),
    nth1(C, K, [G], L),
    set_elems(L, []),
    make_attr(D, M, K, V),
    get_target_module(P),
    N=(get_attr(O, P, Q)->Q=R, (H/\M=:=M->put_attr(O, P, S);T is H\/M, put_attr(O, P, U));put_attr(O, P, V)).
generate_detach_a_constraint(A, [B, D]) :-
    generate_detach_a_constraint_empty_list(A, B),
    get_max_constraint_index(C),
    (   C==1
    ->  generate_detach_a_constraint_1_1(A, D)
    ;   generate_detach_a_constraint_t_p(A, D)
    ).
generate_detach_a_constraint_empty_list(A, D) :-
    make_name(detach_, A, B),
    C=[[], _],
    E=..[B|C],
    D=(E:-true).
generate_detach_a_constraint_1_1(A, I) :-
    make_name(detach_, A, B),
    C=[[F|D], E],
    J=..[B|C],
    H=..[B, D, E],
    generate_detach_body_1(A, F, E, G),
    K=(G, H),
    I=(J:-K).
generate_detach_body_1(_, B, E, A) :-
    get_target_module(C),
    A=(get_attr(B, C, D)->'chr sbag_del_element'(D, E, F), (F==[]->del_attr(B, C);put_attr(B, C, F));true).
generate_detach_a_constraint_t_p(A, I) :-
    make_name(detach_, A, B),
    C=[[F|D], E],
    J=..[B|C],
    H=..[B, D, E],
    generate_detach_body_n(A, F, E, G),
    K=(G, H),
    I=(J:-K).
generate_detach_body_n(A/B, K, P, J) :-
    get_constraint_index(A/B, C),
    or_pattern(C, O),
    and_pattern(C, S),
    get_max_constraint_index(D),
    make_attr(D, H, E, N),
    nth1(C, E, F),
    substitute_eq(F, E, [], G),
    make_attr(D, R, G, T),
    substitute_eq(F, E, Q, I),
    make_attr(D, H, I, U),
    get_target_module(L),
    J=(get_attr(K, L, M)->M=N, (H/\O=:=O->'chr sbag_del_element'(F, P, Q), (Q==[]->R is H/\S, (R==0->del_attr(K, L);put_attr(K, L, T));put_attr(K, L, U));true);true).
generate_indexed_variables_clauses(A, C) :-
    (   forsome(B, A, chr_translate:may_trigger(B))
    ->  generate_indexed_variables_clauses_(A, C)
    ;   C=[]
    ).
generate_indexed_variables_clauses_([], []).
generate_indexed_variables_clauses_([A|E], B) :-
    (   (   is_attached(A)
        ;   chr_pp_flag(debugable, on)
        )
    ->  B=[C|D],
        generate_indexed_variables_clause(A, C)
    ;   B=D
    ),
    generate_indexed_variables_clauses_(E, D).
generate_indexed_variables_clause(A/B, J) :-
    functor(C, A, B),
    get_constraint_mode(A/B, E),
    C=..[_|D],
    create_indexed_variables_body(D,
                                  E,
                                  G,
                                  1,
                                  A/B,
                                  F,
                                  H),
    (   F==empty
    ->  I=(G=[])
    ;   H==0
    ->  I=term_variables(K, G)
    ;   F=I
    ),
    J=('$indexed_variables'(K, G):-K=C, I).
create_indexed_variables_body([], [], _, _, _, empty, 0).
create_indexed_variables_body([I|B], [F|C], J, A, E, H, L) :-
    D is A+1,
    create_indexed_variables_body(B,
                                  C,
                                  K,
                                  D,
                                  E,
                                  G,
                                  M),
    (   F\==(+),
        is_indexed_argument(E, A)
    ->  (   G==empty
        ->  H=term_variables(I, J)
        ;   H=(term_variables(I, J, K), G)
        ),
        L=M
    ;   J=K,
        H=G,
        L is M+1
    ).
generate_extra_clauses(A, [E, F, G, B, H]) :-
    (   chr_pp_flag(reduced_indexing, on)
    ->  global_indexed_variables_clause(A, B)
    ;   B=(chr_indexed_variables(C, D):-'chr chr_indexed_variables'(C, D))
    ),
    generate_remove_clause(E),
    generate_activate_clause(F),
    generate_allocate_clause(G),
    generate_insert_constraint_internal(H).
generate_remove_clause(A) :-
    A=(remove_constraint_internal(B, E, F):-arg(2, B, C), 'chr get_mutable'(D, C), 'chr update_mutable'(removed, C), (compound(D)->E=[], F=no;D==removed->E=[], F=no;F=yes, chr_indexed_variables(B, E))).
generate_activate_clause(A) :-
    A=(activate_constraint(I, H, B, D):-arg(2, B, C), 'chr get_mutable'(G, C), 'chr update_mutable'(active, C), (nonvar(D)->true;arg(4, B, E), 'chr get_mutable'(F, E), D is F+1, 'chr update_mutable'(D, E)), (compound(G)->term_variables(G, H), 'chr none_locked'(H), I=yes;G==removed->chr_indexed_variables(B, H), I=yes;H=[], I=no)).
generate_allocate_clause(A) :-
    A=(allocate_constraint(C, B, D, E):-B=..[suspension, K, J, C, F, H, D|E], 'chr create_mutable'(0, F), 'chr empty_history'(G), 'chr create_mutable'(G, H), chr_indexed_variables(B, I), 'chr create_mutable'(passive(I), J), 'chr gen_id'(K)).
generate_insert_constraint_internal(A) :-
    A=(insert_constraint_internal(yes, F, B, C, D, E):-B=..[suspension, K, G, C, H, J, D|E], chr_indexed_variables(B, F), 'chr none_locked'(F), 'chr create_mutable'(active, G), 'chr create_mutable'(0, H), 'chr empty_history'(I), 'chr create_mutable'(I, J), 'chr gen_id'(K)).
global_indexed_variables_clause(A, F) :-
    (   forsome(B, A, chr_translate:may_trigger(B))
    ->  D=(G=..[_, _, _, _, _, _, C|_], '$indexed_variables'(C, E))
    ;   D=true,
        E=[]
    ),
    F=(chr_indexed_variables(G, E):-D).
generate_attach_increment(B) :-
    get_max_constraint_index(A),
    (   A>0
    ->  B=[C, D],
        generate_attach_increment_empty(C),
        (   A==1
        ->  generate_attach_increment_one(D)
        ;   generate_attach_increment_many(A, D)
        )
    ;   B=[]
    ).
generate_attach_increment_empty((attach_increment([], _):-true)).
generate_attach_increment_one(H) :-
    I=attach_increment([A|G], D),
    get_target_module(B),
    J=('chr not_locked'(A), (get_attr(A, B, C)->sort(C, E), merge(D, E, F), put_attr(A, B, F);put_attr(A, B, D)), attach_increment(G, D)),
    H=(I:-J).
generate_attach_increment_many(A, Z) :-
    make_attr(A, V, C, B),
    make_attr(A, W, D, S),
    A1=attach_increment([P|Y], B),
    bagof(G,
          E^F^H^I^(member2(C, D, E-F), G=(sort(F, H), 'chr merge_attributes'(E, H, I))),
          J),
    list2conj(J, T),
    bagof(N,
          K^L^M^member((K, 'chr merge_attributes'(L, M, N)), J),
          O),
    make_attr(A, U, O, X),
    get_target_module(Q),
    B1=('chr not_locked'(P), (get_attr(P, Q, R)->R=S, T, U is V\/W, put_attr(P, Q, X);put_attr(P, Q, B)), attach_increment(Y, B)),
    Z=(A1:-B1).
generate_attr_unify_hook([B]) :-
    get_max_constraint_index(A),
    (   A==0
    ->  get_target_module(C),
        B=(attr_unify_hook(_, _):-write('ERROR: Unexpected triggering of attr_unify_hook/2 in module '), writeln(C))
    ;   A==1
    ->  generate_attr_unify_hook_one(B)
    ;   generate_attr_unify_hook_many(A, B)
    ).
generate_attr_unify_hook_one(K) :-
    L=attr_unify_hook(A, B),
    get_target_module(C),
    make_run_suspensions(G, H),
    make_run_suspensions(A, J),
    M=(sort(A, E), (var(B)->(get_attr(B, C, D)->true;D=[]), sort(D, F), 'chr merge_attributes'(E, F, G), put_attr(B, C, G), H;(compound(B)->term_variables(B, I), attach_increment(I, E);true), J)),
    K=(L:-M).
generate_attr_unify_hook_many(A, F1) :-
    make_attr(A, Q, C, R),
    make_attr(A, Z, H, W),
    bagof(D,
          B^E^(member(B, C), D=sort(B, E)),
          F),
    list2conj(F, S),
    bagof(E, B^member(sort(B, E), F), G),
    bagof(K,
          I^J^L^M^(member2(G, H, I-J), K=(sort(J, L), 'chr merge_attributes'(I, L, M))),
          O),
    bagof(M,
          I^L^N^member((N, 'chr merge_attributes'(I, L, M)), O),
          P),
    list2conj(O, X),
    make_attr(A, Y, P, A1),
    make_attr(A, Q, G, C1),
    G1=attr_unify_hook(R, T),
    get_target_module(U),
    make_run_suspensions_loop(P, B1),
    make_run_suspensions_loop(G, D1),
    H1=(S, (var(T)->(get_attr(T, U, V)->V=W, X, Y is Q\/Z, put_attr(T, U, A1), B1;put_attr(T, U, C1), D1);(compound(T)->term_variables(T, E1), attach_increment(E1, C1);true), D1)),
    F1=(G1:-H1).
make_run_suspensions(B, A) :-
    (   chr_pp_flag(debugable, on)
    ->  A='chr run_suspensions_d'(B)
    ;   A='chr run_suspensions'(B)
    ).
make_run_suspensions_loop(B, A) :-
    (   chr_pp_flag(debugable, on)
    ->  A='chr run_suspensions_loop_d'(B)
    ;   A='chr run_suspensions_loop'(B)
    ).
generate_insert_delete_constraints([], []).
generate_insert_delete_constraints([A|F], B) :-
    (   is_attached(A)
    ->  B=[C, D|E],
        generate_insert_delete_constraint(A, C, D)
    ;   B=E
    ),
    generate_insert_delete_constraints(F, E).
generate_insert_delete_constraint(A, C, D) :-
    get_store_type(A, B),
    generate_insert_constraint(B, A, C),
    generate_delete_constraint(B, A, D).
generate_insert_constraint(C, A, E) :-
    make_name('$insert_in_store_', A, B),
    F=..[B, D],
    generate_insert_constraint_body(C, A, D, G),
    E=(F:-G).
generate_insert_constraint_body(default, B, C, F) :-
    get_target_module(_),
    get_max_constraint_index(A),
    (   A==1
    ->  generate_attach_body_1(B, D, C, E)
    ;   generate_attach_body_n(B, D, C, E)
    ),
    F=('chr default_store'(D), E).
generate_insert_constraint_body(multi_hash(A), B, C, D) :-
    generate_multi_hash_insert_constraint_bodies(A,
                                                 B,
                                                 C,
                                                 D).
generate_insert_constraint_body(global_ground, A, C, E) :-
    global_ground_store_name(A, B),
    make_get_store_goal(B, D, F),
    make_update_store_goal(B, [C|D], G),
    E=(F, G).
generate_insert_constraint_body(multi_store(B), D, A, G) :-
    find_with_var_identity(E,
                           [A],
                           (member(C, B), chr_translate:generate_insert_constraint_body(C, D, A, E)),
                           F),
    list2conj(F, G).
generate_multi_hash_insert_constraint_bodies([], _, _, true).
generate_multi_hash_insert_constraint_bodies([B|J], A, C,  (E, K)) :-
    multi_hash_store_name(A, B, D),
    multi_hash_key(A, B, C, F, I),
    make_get_store_goal(D, H, G),
    E=(F, G, insert_ht(H, I, C)),
    generate_multi_hash_insert_constraint_bodies(J,
                                                 A,
                                                 C,
                                                 K).
generate_delete_constraint(C, A, E) :-
    make_name('$delete_from_store_', A, B),
    F=..[B, D],
    generate_delete_constraint_body(C, A, D, G),
    E=(F:-G).
generate_delete_constraint_body(default, B, C, D) :-
    get_target_module(_),
    get_max_constraint_index(A),
    (   A==1
    ->  generate_detach_body_1(B, E, C, F),
        D=('chr default_store'(E), F)
    ;   generate_detach_body_n(B, E, C, F),
        D=('chr default_store'(E), F)
    ).
generate_delete_constraint_body(multi_hash(A), B, C, D) :-
    generate_multi_hash_delete_constraint_bodies(A,
                                                 B,
                                                 C,
                                                 D).
generate_delete_constraint_body(global_ground, A, F, C) :-
    global_ground_store_name(A, B),
    make_get_store_goal(B, E, D),
    make_update_store_goal(B, G, H),
    C=(D, 'chr sbag_del_element'(E, F, G), H).
generate_delete_constraint_body(multi_store(B), D, A, G) :-
    find_with_var_identity(E,
                           [A],
                           (member(C, B), chr_translate:generate_delete_constraint_body(C, D, A, E)),
                           F),
    list2conj(F, G).
generate_multi_hash_delete_constraint_bodies([], _, _, true).
generate_multi_hash_delete_constraint_bodies([B|J], A, C,  (E, K)) :-
    multi_hash_store_name(A, B, D),
    multi_hash_key(A, B, C, F, I),
    make_get_store_goal(D, H, G),
    E=(F, G, delete_ht(H, I, C)),
    generate_multi_hash_delete_constraint_bodies(J,
                                                 A,
                                                 C,
                                                 K).
generate_delete_constraint_call(A, D, B) :-
    make_name('$delete_from_store_', A, C),
    B=..[C, D].
generate_insert_constraint_call(A, D, B) :-
    make_name('$insert_in_store_', A, C),
    B=..[C, D].
generate_store_code(A, [B|C]) :-
    enumerate_stores_code(A, B),
    generate_store_code(A, C, []).
generate_store_code([], A, A).
generate_store_code([A|D], C, F) :-
    get_store_type(A, B),
    generate_store_code(B, A, C, E),
    generate_store_code(D, E, F).
generate_store_code(default, _, A, A).
generate_store_code(multi_hash(A), B, C, E) :-
    multi_hash_store_initialisations(A, B, C, D),
    multi_hash_via_lookups(A, B, D, E).
generate_store_code(global_ground, A, B, C) :-
    global_ground_store_initialisation(A, B, C).
generate_store_code(multi_store(A), B, C, D) :-
    multi_store_generate_store_code(A, B, C, D).
multi_store_generate_store_code([], _, A, A).
multi_store_generate_store_code([A|D], B, C, F) :-
    generate_store_code(A, B, C, E),
    multi_store_generate_store_code(D, B, E, F).
multi_hash_store_initialisations([], _, A, A).
multi_hash_store_initialisations([B|G], A, D, I) :-
    multi_hash_store_name(A, B, C),
    make_init_store_goal(C, E, F),
    D=[(:-new_ht(E), F)|H],
    multi_hash_store_initialisations(G, A, H, I).
global_ground_store_initialisation(A, C, E) :-
    global_ground_store_name(A, B),
    make_init_store_goal(B, [], D),
    C=[(:-D)|E].
multi_hash_via_lookups([], _, A, A).
multi_hash_via_lookups([B|L], A, I, N) :-
    multi_hash_via_lookup_name(A, B, C),
    J=..[C, G, H],
    multi_hash_store_name(A, B, D),
    make_get_store_goal(D, F, E),
    K=(E, lookup_ht(F, G, H)),
    I=[(J:-K)|M],
    multi_hash_via_lookups(L, A, M, N).
multi_hash_via_lookup_name(C/D, A, E) :-
    (   integer(A)
    ->  B=A
    ;   is_list(A)
    ->  atom_concat_list(A, B)
    ),
    atom_concat_list(['$via1_multi_hash_', C, /, D, -, B], E).
multi_hash_store_name(D/E, A, F) :-
    get_target_module(C),
    (   integer(A)
    ->  B=A
    ;   is_list(A)
    ->  atom_concat_list(A, B)
    ),
    atom_concat_list(
                     [ '$chr_store_multi_hash_',
                       C,
                       (:),
                       D,
                       (/),
                       E,
                       (-),
                       B
                     ],
                     F).
multi_hash_key(_/_, A, E, C, F) :-
    (   (   integer(A)
        ->  B=A
        ;   A=[B]
        )
    ->  D is B+6,
        C=arg(D, E, F)
    ;   is_list(A)
    ->  sort(A, H),
        find_with_var_identity(arg(I, E, G)-G,
                               [E],
                               (member(B, H), I is B+6),
                               J),
        pairup(L, K, J),
        F=..[k|K],
        list2conj(L, C)
    ).
multi_hash_key_args(A, B, C) :-
    (   integer(A)
    ->  arg(A, B, D),
        C=[D]
    ;   is_list(A)
    ->  sort(A, F),
        term_variables(B, E),
        find_with_var_identity(D,
                               E,
                               (member(G, F), arg(G, B, D)),
                               C)
    ).
global_ground_store_name(B/C, D) :-
    get_target_module(A),
    atom_concat_list(['$chr_store_global_ground_', A, :, B, /, C],
                     D).
enumerate_stores_code(A, D) :-
    E='$enumerate_suspensions'(B),
    enumerate_store_bodies(A, B, C),
    list2disj(C, F),
    D=(E:-F).
enumerate_store_bodies([], _, []).
enumerate_store_bodies([A|G], C, D) :-
    (   is_attached(A)
    ->  get_store_type(A, B),
        enumerate_store_body(B, A, C, E),
        D=[E|F]
    ;   D=F
    ),
    enumerate_store_bodies(G, C, F).
enumerate_store_body(default, A, H, K) :-
    get_constraint_index(A, E),
    get_target_module(C),
    get_max_constraint_index(D),
    L=('chr default_store'(B), get_attr(B, C, G)),
    (   D>1
    ->  F is E+1,
        J=(arg(F, G, I), member(H, I))
    ;   J=member(H, G)
    ),
    K=(L, J).
enumerate_store_body(multi_hash([A|_]), B, C, D) :-
    multi_hash_enumerate_store_body(A, B, C, D).
enumerate_store_body(global_ground, A, E, C) :-
    global_ground_store_name(A, B),
    make_get_store_goal(B, F, D),
    C=(D, member(E, F)).
enumerate_store_body(multi_store(A), C, D, E) :-
    once(( member(B, A),
           enumerate_store_body(B, C, D, E)
         )).
multi_hash_enumerate_store_body(B, A, G, D) :-
    multi_hash_store_name(A, B, C),
    make_get_store_goal(C, F, E),
    D=(E, value_ht(F, G)).
check_attachments(A) :-
    (   chr_pp_flag(check_attachments, on)
    ->  check_constraint_attachments(A)
    ;   true
    ).
check_constraint_attachments([]).
check_constraint_attachments([A|B]) :-
    check_constraint_attachment(A),
    check_constraint_attachments(B).
check_constraint_attachment(A) :-
    get_max_occurrence(A, B),
    check_occurrences_attachment(A, 1, B).
check_occurrences_attachment(C, A, B) :-
    (   A>B
    ->  true
    ;   check_occurrence_attachment(C, A),
        D is A+1,
        check_occurrences_attachment(C, D, B)
    ).
check_occurrence_attachment(A, B) :-
    get_occurrence(A, B, C, E),
    get_rule(C, D),
    D=pragma(rule(G, I, J, M), ids(F, K), _, _, _),
    (   select2(E, H, F, G, _, _)
    ->  check_attachment_head1(H,
                               E,
                               C,
                               G,
                               I,
                               J)
    ;   select2(E, L, K, I, _, _)
    ->  check_attachment_head2(L, E, C, G, M)
    ).
check_attachment_head1(A, G, F, B, C, D) :-
    functor(A, H, I),
    (   B==[A],
        C==[],
        D==true,
        A=..[_|E],
        no_matching(E, []),
        \+ is_passive(F, G)
    ->  attached(H/I, no)
    ;   attached(H/I, maybe)
    ).
no_matching([], _).
no_matching([A|C], B) :-
    var(A),
    \+ memberchk_eq(A, B),
    no_matching(C, [A|B]).
check_attachment_head2(A, C, B, F, G) :-
    functor(A, D, E),
    (   is_passive(B, C)
    ->  attached(D/E, maybe)
    ;   F\==[],
        G==true
    ->  attached(D/E, maybe)
    ;   attached(D/E, yes)
    ).
all_attached([]).
all_attached([A|D]) :-
    functor(A, B, C),
    is_attached(B/C),
    all_attached(D).
set_constraint_indices([], A) :-
    B is A-1,
    max_constraint_index(B).
set_constraint_indices([A|C], B) :-
    (   (   may_trigger(A)
        ;   is_attached(A),
            get_store_type(A, default)
        )
    ->  constraint_index(A, B),
        D is B+1,
        set_constraint_indices(C, D)
    ;   set_constraint_indices(C, B)
    ).
constraints_code(A, B, D) :-
    post_constraints(A, 1),
    constraints_code1(1, B, C, []),
    clean_clauses(C, D).
post_constraints([], A) :-
    B is A-1,
    constraint_count(B).
post_constraints([A/B|D], C) :-
    constraint(A/B, C),
    E is C+1,
    post_constraints(D, E).
constraints_code1(A, E, D, C) :-
    get_constraint_count(B),
    (   A>B
    ->  C=D
    ;   constraint_code(A, E, D, G),
        F is A+1,
        constraints_code1(F, E, G, C)
    ).
constraint_code(A, E, C, J) :-
    get_constraint(B, A),
    constraint_prelude(B, D),
    C=[D|G],
    F=[0],
    rules_code(E, A, F, H, G, I),
    gen_cond_attach_clause(B, H, I, J).
constraint_prelude(B/A, E) :-
    vars_susp(A, C, I, D),
    F=..[B|C],
    build_head(B, A, [0], D, H),
    get_target_module(G),
    J=..[B|C],
    (   chr_pp_flag(debugable, on)
    ->  E=(F:-allocate_constraint(G:H, I, J, C), ('chr debug_event'(call(I)), H;'chr debug_event'(fail(I)), !, fail), ('chr debug_event'(exit(I));'chr debug_event'(redo(I)), fail))
    ;   E=(F:-H)
    ).
gen_cond_attach_clause(A/B, C, K, M) :-
    (   is_attached(A/B)
    ->  (   C==[0]
        ->  (   may_trigger(A/B)
            ->  gen_cond_attach_goal(A/B,
                                     D,
                                     E,
                                     F,
                                     G)
            ;   gen_insert_constraint_internal_goal(A/B,
                                                    D,
                                                    E,
                                                    F,
                                                    G)
            )
        ;   vars_susp(B, F, G, E),
            gen_uncond_attach_goal(A/B, G, D, _)
        ),
        (   chr_pp_flag(debugable, on)
        ->  H=..[A|F],
            I='chr debug_event'(insert(#(H, G)))
        ;   I=true
        ),
        build_head(A, B, C, E, J),
        L=(J:-I, D),
        K=[L|M]
    ;   K=M
    ).
gen_cond_attach_goal(E/A, H, D, B, C) :-
    vars_susp(A, B, C, D),
    build_head(E, A, [0], D, K),
    (   may_trigger(E/A)
    ->  make_name(attach_, E/A, F),
        G=..[F, I, C]
    ;   G=true
    ),
    get_target_module(J),
    L=..[E|B],
    generate_insert_constraint_call(E/A, C, N),
    H=((var(C)->insert_constraint_internal(M, I, C, J:K, L, B);activate_constraint(M, I, C, _)), (M==yes->N, G;true)).
gen_insert_constraint_internal_goal(E/A, H, D, B, C) :-
    vars_susp(A, B, C, D),
    build_head(E, A, [0], D, K),
    (   may_trigger(E/A)
    ->  make_name(attach_, E/A, F),
        G=..[F, I, C]
    ;   G=true
    ),
    get_target_module(J),
    L=..[E|B],
    generate_insert_constraint_call(E/A, C, M),
    H=(insert_constraint_internal(_, I, C, J:K, L, B), M, G).
gen_uncond_attach_goal(A, C, E, G) :-
    (   may_trigger(A)
    ->  make_name(attach_, A, B),
        D=..[B, F, C]
    ;   D=true
    ),
    generate_insert_constraint_call(A, C, I),
    E=(activate_constraint(H, F, C, G), (H==yes->I, D;true)).
rules_code([], _, A, A, B, B).
rules_code([A|E], B, C, G, D, I) :-
    rule_code(A, B, C, F, D, H),
    rules_code(E, B, F, G, H, I).
rule_code(A, F, G, K, H, M) :-
    A=pragma(C, B, _, _, _),
    B=ids(E, J),
    C=rule(D, I, _, _),
    heads1_code(D,
                [],
                E,
                [],
                A,
                F,
                G,
                H,
                L),
    heads2_code(I,
                [],
                J,
                [],
                A,
                F,
                G,
                K,
                L,
                M).
heads1_code([], _, _, _, _, _, _, A, A).
heads1_code([C|J], H, [G|L], M, A, B, P, Q, S) :-
    A=pragma(I, _, _, _, F),
    get_constraint(D/E, B),
    (   functor(C, D, E),
        \+ is_passive(F, G),
        \+ check_unnecessary_active(C, H, I),
        all_attached(J),
        all_attached(H),
        I=rule(_, K, _, _),
        all_attached(K)
    ->  append(J, H, N),
        append(L, M, O),
        head1_code(C,
                   N,
                   O,
                   A,
                   D/E,
                   B,
                   P,
                   Q,
                   R)
    ;   Q=R
    ),
    heads1_code(J,
                [C|H],
                L,
                [G|M],
                A,
                B,
                P,
                R,
                S).
head1_code(E, F, G, A, J, _, K, L, M) :-
    A=pragma(B, _, _, _, D),
    B=rule(_, C, _, _),
    (   C==[]
    ->  reorder_heads(D, E, F, G, H, I),
        simplification_code(E,
                            H,
                            I,
                            A,
                            J,
                            K,
                            L,
                            M)
    ;   simpagation_head1_code(E,
                               F,
                               G,
                               A,
                               J,
                               K,
                               L,
                               M)
    ).
heads2_code([], _, _, _, _, _, A, A, B, B).
heads2_code([C|J], H, [G|L], M, A, B, Q, V, R, W) :-
    A=pragma(I, _, _, _, F),
    get_constraint(D/E, B),
    (   functor(C, D, E),
        \+ is_passive(F, G),
        \+ check_unnecessary_active(C, H, I),
        \+ set_semantics_rule(A),
        all_attached(J),
        all_attached(H),
        I=rule(K, _, _, _),
        all_attached(K)
    ->  append(J, H, N),
        append(L, M, O),
        length(J, P),
        head2_code(C,
                   N,
                   O,
                   A,
                   P,
                   D/E,
                   Q,
                   R,
                   S),
        inc_id(Q, U),
        gen_alloc_inc_clause(D/E, Q, S, T)
    ;   R=T,
        U=Q
    ),
    heads2_code(J,
                [C|H],
                L,
                [G|M],
                A,
                B,
                U,
                V,
                T,
                W).
head2_code(E, F, G, A, I, J, K, L, M) :-
    A=pragma(B, _, _, _, D),
    B=rule(C, _, _, _),
    (   C==[]
    ->  reorder_heads(D, E, F, G, H, _),
        propagation_code(E,
                         H,
                         B,
                         D,
                         I,
                         J,
                         K,
                         L,
                         M)
    ;   simpagation_head2_code(E,
                               F,
                               G,
                               A,
                               J,
                               K,
                               L,
                               M)
    ).
gen_alloc_inc_clause(B/A, C, K, M) :-
    vars_susp(A, F, G, D),
    build_head(B, A, C, D, H),
    inc_id(C, E),
    build_head(B, A, E, D, J),
    gen_allocation(C, F, G, B/A, D, I),
    L=(H:-I, J),
    K=[L|M].
gen_cond_allocation(A, B, C, D, E) :-
    gen_allocation(A, B, C, D, F),
    E=(var(B)->F;true).
gen_allocation(D, H, A/B, C, E) :-
    build_head(A, B, [0], C, G),
    get_target_module(F),
    I=..[A|D],
    E=allocate_constraint(F:G, H, I, D).
gen_allocation(A, C, D, B, E, F) :-
    (   A==[0]
    ->  (   is_attached(B)
        ->  (   may_trigger(B)
            ->  gen_cond_allocation(C, D, B, E, F)
            ;   gen_allocation(C, D, B, E, F)
            )
        ;   F=true
        )
    ;   F=true
    ).
guard_via_reschedule(A, B, C, D) :-
    (   chr_pp_flag(guard_via_reschedule, on)
    ->  guard_via_reschedule_main(A, B, C, D)
    ;   append(A, B, E),
        list2conj(E, D)
    ).
guard_via_reschedule_main(B, C, A, G) :-
    initialize_unit_dictionary(A, D),
    build_units(B, C, D, E),
    dependency_reorder(E, F),
    units2goal(F, G).
units2goal([], true).
units2goal([unit(_, A, _, _)|B],  (A, C)) :-
    units2goal(B, C).
dependency_reorder(A, B) :-
    dependency_reorder(A, [], B).
dependency_reorder([], A, B) :-
    reverse(A, B).
dependency_reorder([A|F], C, G) :-
    A=unit(_, _, B, D),
    (   B==fixed
    ->  E=[A|C]
    ;   dependency_insert(C, A, D, E)
    ),
    dependency_reorder(F, E, G).
dependency_insert([], A, _, [A]).
dependency_insert([A|F], E, C, D) :-
    A=unit(B, _, _, _),
    (   memberchk(B, C)
    ->  D=[E, A|F]
    ;   D=[A|G],
        dependency_insert(F, E, C, G)
    ).
build_units(A, D, B, C) :-
    build_retrieval_units(A, 1, E, B, F, C, G),
    build_guard_units(D, E, F, G).
build_retrieval_units([], A, A, B, B, C, C).
build_retrieval_units([A|G], C, I, D, K, E, M) :-
    term_variables(A, B),
    update_unit_dictionary(B, C, D, J, [], F),
    E=[unit(C, A, movable, F)|L],
    H is C+1,
    build_retrieval_units2(G,
                           H,
                           I,
                           J,
                           K,
                           L,
                           M).
build_retrieval_units2([], A, A, B, B, C, C).
build_retrieval_units2([A|G], C, I, D, K, E, M) :-
    term_variables(A, B),
    update_unit_dictionary(B, C, D, J, [], F),
    E=[unit(C, A, fixed, F)|L],
    H is C+1,
    build_retrieval_units(G,
                          H,
                          I,
                          J,
                          K,
                          L,
                          M).
initialize_unit_dictionary(A, C) :-
    term_variables(A, B),
    pair_all_with(B, 0, C).
update_unit_dictionary([], _, A, A, B, B).
update_unit_dictionary([B|H], D, A, I, E, J) :-
    (   lookup_eq(A, B, C)
    ->  (   (   C==D
            ;   memberchk(C, E)
            )
        ->  F=E
        ;   F=[C|E]
        ),
        G=A
    ;   G=[B-D|A],
        F=E
    ),
    update_unit_dictionary(H, D, G, I, F, J).
build_guard_units(A, C, F, B) :-
    (   A=[D]
    ->  B=[unit(C, D, fixed, [])]
    ;   A=[D|H]
    ->  term_variables(D, E),
        update_unit_dictionary2(E, C, F, J, [], G),
        B=[unit(C, D, movable, G)|K],
        I is C+1,
        build_guard_units(H, I, J, K)
    ).
update_unit_dictionary2([], _, A, A, B, B).
update_unit_dictionary2([B|H], D, A, I, E, J) :-
    (   lookup_eq(A, B, C)
    ->  (   (   C==D
            ;   memberchk(C, E)
            )
        ->  F=E
        ;   F=[C|E]
        ),
        G=[B-D|A]
    ;   G=[B-D|A],
        F=E
    ),
    update_unit_dictionary2(H, D, G, I, F, J).
unique_analyse_optimise(A, B) :-
    (   chr_pp_flag(unique_analyse_optimise, on)
    ->  unique_analyse_optimise_main(A, 1, [], B)
    ;   B=A
    ).
unique_analyse_optimise_main([], _, _, []).
unique_analyse_optimise_main([A|S], B, D, [P|U]) :-
    (   discover_unique_pattern(A, B, C)
    ->  E=[C|D]
    ;   E=D
    ),
    A=pragma(F, G, O, R, M),
    F=rule(H, J, _, _),
    G=ids(I, K),
    apply_unique_patterns_to_constraints(H, I, E, L),
    apply_unique_patterns_to_constraints(J, K, E, N),
    globalize_unique_pragmas(L, M),
    globalize_unique_pragmas(N, M),
    append([L, N, O], Q),
    P=pragma(F, G, Q, R, M),
    T is B+1,
    unique_analyse_optimise_main(S, T, E, U).
globalize_unique_pragmas([], _).
globalize_unique_pragmas([unique(B, C)|D], A) :-
    pragma_unique(A, B, C),
    globalize_unique_pragmas(D, A).
apply_unique_patterns_to_constraints([], _, _, []).
apply_unique_patterns_to_constraints([B|H], [C|I], A, E) :-
    (   member(D, A),
        apply_unique_pattern(B, C, D, F)
    ->  E=[F|G]
    ;   E=G
    ),
    apply_unique_patterns_to_constraints(H, I, A, G).
apply_unique_pattern(B, M, A, L) :-
    A=unique(C, E),
    subsumes(B, C, D),
    find_with_var_identity(H,
                           D,
                           (member(F, E), lookup_eq(D, F, G), term_variables(G, I), member(H, I)),
                           J),
    sort(J, K),
    N=K,
    L=unique(M, N).
subsumes(A, B, F) :-
    empty_ds(C),
    subsumes_aux(A, B, C, D),
    ds_to_list(D, E),
    build_unifier(E, F).
subsumes_aux(B, A, E, F) :-
    (   compound(A),
        functor(A, C, D)
    ->  compound(B),
        functor(B, C, D),
        subsumes_aux(D, B, A, E, F)
    ;   B==A
    ->  F=E
    ;   var(A),
        get_ds(B, E, G)
    ->  G==A,
        F=E
    ;   var(A),
        put_ds(B, E, A, F)
    ).
subsumes_aux(0, _, _, A, A) :-
    !.
subsumes_aux(A, B, C, F, I) :-
    arg(A, B, D),
    arg(A, C, E),
    subsumes_aux(D, E, F, H),
    G is A-1,
    subsumes_aux(G, B, C, H, I).
build_unifier([], []).
build_unifier([B-A|C], [A-B|D]) :-
    build_unifier(C, D).
discover_unique_pattern(A, B, M) :-
    A=pragma(C, _, _, N, B),
    C=rule(D, E, H, _),
    (   D=[F],
        E=[G]
    ->  true
    ;   D=[F, G],
        E==[]
    ->  true
    ),
    check_unique_constraints(F, G, H, B, I),
    term_variables(F, J),
    select_pragma_unique_variables(I, J, K),
    L=unique(F, K),
    copy_term_nat(L, M),
    (   verbosity_on
    ->  format('Found unique pattern ~w in rule ~d~@\n',
               
               [ M,
                 B,
                 (N=yes(O)->write(": "), write(O);true)
               ])
    ;   true
    ).
select_pragma_unique_variables([], _, []).
select_pragma_unique_variables([A-B|F], D, C) :-
    (   A==B
    ->  C=[A|E]
    ;   once((   \+ memberchk_eq(A, D)
             ;   \+ memberchk_eq(B, D)
             )),
        C=E
    ),
    select_pragma_unique_variables(F, D, E).
check_unique_constraints(B, C, E, A, D) :-
    \+ any_passive_head(A),
    variable_replacement(B-C, C-B, D),
    copy_with_variable_replacement(E, G, D),
    negate_b(E, F),
    once(entails_b(F, G)).
check_unnecessary_active(A, B, C) :-
    (   chr_pp_flag(check_unnecessary_active, full)
    ->  check_unnecessary_active_main(A, B, C)
    ;   chr_pp_flag(check_unnecessary_active, simplification),
        C=rule(_, [], _, _)
    ->  check_unnecessary_active_main(A, B, C)
    ;   fail
    ).
check_unnecessary_active_main(C, A, D) :-
    member(B, A),
    variable_replacement(B, C, E),
    copy_with_variable_replacement(D, F, E),
    identical_rules(D, F),
    !.
set_semantics_rule(A) :-
    (   chr_pp_flag(set_semantics_rule, on)
    ->  set_semantics_rule_main(A)
    ;   fail
    ).
set_semantics_rule_main(A) :-
    A=pragma(B, C, E, _, I),
    B=rule([_], [_], true, _),
    C=ids([D], [F]),
    once(member(unique(D, G), E)),
    once(member(unique(F, H), E)),
    G==H,
    \+ is_passive(I, D).
identical_rules(rule(E, H, A, C), rule(G, J, B, D)) :-
    A==B,
    identical_bodies(C, D),
    permutation(E, F),
    F==G,
    permutation(H, I),
    I==J.
identical_bodies(A, B) :-
    (   A=(C=E),
        B=(D=F)
    ->  (   C==D,
            E==F
        ;   C==F,
            D==E
        ),
        !
    ;   A==B
    ).
copy_with_variable_replacement(A, C, B) :-
    (   var(A)
    ->  (   lookup_eq(B, A, C)
        ->  true
        ;   A=C
        )
    ;   functor(A, D, E),
        functor(C, D, E),
        A=..[_|F],
        C=..[_|G],
        copy_with_variable_replacement_l(F, G, B)
    ).
copy_with_variable_replacement_l([], [], _).
copy_with_variable_replacement_l([A|D], [B|E], C) :-
    copy_with_variable_replacement(A, B, C),
    copy_with_variable_replacement_l(D, E, C).
variable_replacement(A, B, C) :-
    variable_replacement(A, B, [], C).
variable_replacement(A, B, C, E) :-
    (   var(A)
    ->  var(B),
        (   lookup_eq(C, A, D)
        ->  D==B,
            E=C
        ;   E=[A-B|C]
        )
    ;   A=..[F|G],
        nonvar(B),
        B=..[F|H],
        variable_replacement_l(G, H, C, E)
    ).
variable_replacement_l([], [], A, A).
variable_replacement_l([A|D], [B|E], C, G) :-
    variable_replacement(A, B, C, F),
    variable_replacement_l(D, E, F, G).
simplification_code(B, H, J, A, D/C, E, E1, G1) :-
    A=pragma(O, _, K, _, _),
    head_info(B, C, _, S, F, G),
    build_head(D, C, E, F, Q),
    head_arg_matches(G, [], R, I),
    (   H==[]
    ->  M=[],
        N=I,
        L=[]
    ;   rest_heads_retrieval_and_matching(H,
                                          J,
                                          K,
                                          B,
                                          L,
                                          M,
                                          I,
                                          N)
    ),
    guard_body_copies2(O, N, P, D1),
    guard_via_reschedule(L, P, Q-R, A1),
    gen_uncond_susps_detachments(M, H, B1),
    gen_cond_susp_detachment(E, S, D/C, C1),
    (   chr_pp_flag(debugable, on)
    ->  O=rule(_, _, T, U),
        my_term_copy(T-U, N, _, V-W),
        Y='chr debug_event'(try([S|X], [], V, W)),
        Z='chr debug_event'(apply([S|X], [], V, W))
    ;   Y=true,
        Z=true
    ),
    F1=(Q:-R, A1, Y, !, Z, B1, C1, D1),
    E1=[F1|G1].
head_arg_matches(A, B, E, C) :-
    head_arg_matches_(A, B, D, C),
    list2conj(D, E).
head_arg_matches_([], A, [], A).
head_arg_matches_([A-D|H], B, C, P) :-
    (   var(A)
    ->  (   lookup_eq(B, A, E)
        ->  C=[D==E|G],
            F=B
        ;   F=[A-D|B],
            C=G
        ),
        I=H
    ;   atomic(A)
    ->  C=[D==A|G],
        B=F,
        I=H
    ;   A=..[_|M],
        functor(A, J, K),
        functor(L, J, K),
        L=..[_|N],
        C=[nonvar(D), D=L|G],
        pairup(M, N, O),
        append(O, H, I),
        F=B
    ),
    head_arg_matches_(I, F, G, P).
rest_heads_retrieval_and_matching(A, B, C, D, E, F, G, H) :-
    rest_heads_retrieval_and_matching(A,
                                      B,
                                      C,
                                      D,
                                      E,
                                      F,
                                      G,
                                      H,
                                      [],
                                      [],
                                      []).
rest_heads_retrieval_and_matching(A, B, C, F, G, H, I, J, D, E, K) :-
    (   A=[_|_]
    ->  rest_heads_retrieval_and_matching_n(A,
                                            B,
                                            C,
                                            D,
                                            E,
                                            F,
                                            G,
                                            H,
                                            I,
                                            J,
                                            K)
    ;   G=[],
        H=[],
        I=J
    ).
rest_heads_retrieval_and_matching_n([], _, _, _, _, _, [], [], A, A, B) :-
    instantiate_pattern_goals(B).
rest_heads_retrieval_and_matching_n([A|D1], [Y|E1], Z, F, S, E, [I, B1|F1], [R|G1], H, I1, G) :-
    functor(A, B, C),
    get_store_type(B/C, D),
    (   D==default
    ->  passive_head_via(A,
                         [E|F],
                         G,
                         H,
                         I,
                         K,
                         O),
        get_max_constraint_index(J),
        (   J==1
        ->  N=K
        ;   get_constraint_index(B/C, L),
            make_attr(J, _, M, K),
            nth1(L, M, N)
        )
    ;   lookup_passive_head(D,
                            A,
                            [E|F],
                            H,
                            I,
                            N),
        O=G
    ),
    head_info(A, C, Q, _, _, P),
    head_arg_matches(P, H, X, H1),
    U=..[suspension, _, T, _, _, _, _|Q],
    different_from_other_susps(A, R, F, S, W),
    create_get_mutable_ref(active, T, V),
    C1=(member(R, N), R=U, V, W, X),
    (   member(unique(Y, A1), Z),
        check_unique_keys(A1, H)
    ->  B1=(C1->true)
    ;   B1=C1
    ),
    rest_heads_retrieval_and_matching_n(D1,
                                        E1,
                                        Z,
                                        [A|F],
                                        [R|S],
                                        E,
                                        F1,
                                        G1,
                                        H1,
                                        I1,
                                        O).
instantiate_pattern_goals([]).
instantiate_pattern_goals([_-attr(C, D, B)|G]) :-
    get_max_constraint_index(A),
    (   A==1
    ->  B=true
    ;   make_attr(A, E, _, C),
        or_list(D, F),
        !,
        B=(E/\F=:=F)
    ),
    instantiate_pattern_goals(G).
check_unique_keys([], _).
check_unique_keys([B|C], A) :-
    lookup_eq(A, B, _),
    check_unique_keys(C, A).
different_from_other_susps(C, G, B, E, J) :-
    (   bagof(F,
              A^(nth1(A, B, D), \+C\=D, nth1(A, E, H), F=(G\==H)),
              I)
    ->  list2conj(I, J)
    ;   J=true
    ).
passive_head_via(A, D, I, F, O, K, N) :-
    functor(A, B, C),
    get_constraint_index(B/C, G),
    common_variables(A, D, E),
    translate(E, F, H),
    or_pattern(G, L),
    (   permutation(H, J),
        lookup_eq(I, J, attr(K, M, _))
    ->  member(L, M),
        !,
        N=I,
        O=true
    ;   O=(P, Q),
        gen_get_mod_constraints(H, P, K),
        N=[H-attr(K, [L|_], Q)|I]
    ).
common_variables(A, B, E) :-
    term_variables(A, C),
    term_variables(B, D),
    intersect_eq(C, D, E).
gen_get_mod_constraints(A, B, F) :-
    get_target_module(D),
    (   A==[]
    ->  B=('chr default_store'(C), get_attr(C, D, E), E=F)
    ;   (   A=[G]
        ->  H='chr via_1'(G, J)
        ;   A=[G, I]
        ->  H='chr via_2'(G, I, J)
        ;   H='chr via'(A, J)
        ),
        B=(H, get_attr(J, D, E), E=F)
    ).
guard_body_copies(A, B, E, C) :-
    guard_body_copies2(A, B, D, C),
    list2conj(D, E).
guard_body_copies2(A, D, H, W) :-
    A=rule(_, _, B, U),
    conj2list(B, C),
    split_off_simple_guard(C, D, E, F),
    my_term_copy(E-F, D, V, G-I),
    append(G, [Q], H),
    term_variables(F, K),
    term_variables(I, M),
    (   chr_pp_flag(guard_locks, on),
        find_with_var_identity('chr lock'(J)-'chr unlock'(J),
                               D,
                               (member(L, K), lookup_eq(D, L, J), memberchk_eq(J, M)),
                               N)
    ->  once(pairup(O, P, N))
    ;   O=[],
        P=[]
    ),
    list2conj(O, R),
    list2conj(P, T),
    list2conj(I, S),
    Q=(R, S, T),
    my_term_copy(U, V, W).
split_off_simple_guard([], _, [], []).
split_off_simple_guard([A|D], B, C, F) :-
    (   simple_guard(A, B)
    ->  C=[A|E],
        split_off_simple_guard(D, B, E, F)
    ;   C=[],
        F=[A|D]
    ).
simple_guard(A, C) :-
    binds_b(A, B),
    not(( member(D, B),
          lookup_eq(C, D, _)
        )).
my_term_copy(A, B, C) :-
    my_term_copy(A, B, _, C).
my_term_copy(A, B, D, C) :-
    (   var(A)
    ->  (   lookup_eq(B, A, C)
        ->  D=B
        ;   D=[A-C|B]
        )
    ;   functor(A, E, F),
        functor(C, E, F),
        A=..[_|G],
        C=..[_|H],
        my_term_copy_list(G, B, D, H)
    ).
my_term_copy_list([], A, A, []).
my_term_copy_list([A|D], B, F, [C|G]) :-
    my_term_copy(A, B, E, C),
    my_term_copy_list(D, E, F, G).
gen_cond_susp_detachment(B, D, A, C) :-
    (   is_attached(A)
    ->  (   B==[0],
            \+ may_trigger(A)
        ->  C=true
        ;   gen_uncond_susp_detachment(D, A, E),
            C=(var(D)->true;E)
        )
    ;   C=true
    ).
gen_uncond_susp_detachment(C, A, F) :-
    (   is_attached(A)
    ->  (   may_trigger(A)
        ->  make_name(detach_, A, B),
            D=..[B, G, C]
        ;   D=true
        ),
        (   chr_pp_flag(debugable, on)
        ->  E='chr debug_event'(remove(C))
        ;   E=true
        ),
        generate_delete_constraint_call(A, C, I),
        F=(E, remove_constraint_internal(C, G, H), (H==yes->I, D;true))
    ;   F=true
    ).
gen_uncond_susps_detachments([], [], true).
gen_uncond_susps_detachments([B|F], [A|G],  (E, H)) :-
    functor(A, C, D),
    gen_uncond_susp_detachment(B, C/D, E),
    gen_uncond_susps_detachments(F, G, H).
simpagation_head1_code(C, I, K, A, F/D, G, M1, O1) :-
    A=pragma(B, ids(_, L), R, _, M),
    B=rule(_, J, B1, C1),
    head_info(C, D, _, A1, H, E),
    head_arg_matches(E, [], Y, S),
    build_head(F, D, G, H, X),
    append(I, J, N),
    append(K, L, O),
    reorder_heads(M, C, N, O, P, Q),
    rest_heads_retrieval_and_matching(P,
                                      Q,
                                      R,
                                      C,
                                      V,
                                      T,
                                      S,
                                      U),
    split_by_ids(Q, T, K, Z, D1),
    guard_body_copies2(B, U, W, L1),
    guard_via_reschedule(V, W, X-Y, I1),
    gen_uncond_susps_detachments(Z, I, J1),
    gen_cond_susp_detachment(G, A1, F/D, K1),
    (   chr_pp_flag(debugable, on)
    ->  my_term_copy(B1-C1, U, _, E1-F1),
        G1='chr debug_event'(try([A1|Z], D1, E1, F1)),
        H1='chr debug_event'(apply([A1|Z], D1, E1, F1))
    ;   G1=true,
        H1=true
    ),
    N1=(X:-Y, I1, G1, !, H1, J1, K1, L1),
    M1=[N1|O1].
split_by_ids([], [], _, [], []).
split_by_ids([A|H], [D|I], B, C, E) :-
    (   memberchk_eq(A, B)
    ->  C=[D|F],
        E=G
    ;   C=F,
        E=[D|G]
    ),
    split_by_ids(H, I, B, F, G).
simpagation_head2_code(D, H, Q, A, K, L, M, T) :-
    A=pragma(B, ids(F, _), _, _, C),
    B=rule(E, _, I, J),
    reorder_heads(C,
                  D,
                  E,
                  F,
                  [G|O],
                  [N|P]),
    simpagation_head2_prelude(D,
                              G,
                              [H, E, I, J],
                              K,
                              L,
                              M,
                              S),
    extend_id(L, R),
    simpagation_head2_worker(D,
                             G,
                             N,
                             O,
                             P,
                             H,
                             Q,
                             A,
                             K,
                             R,
                             S,
                             T).
simpagation_head2_prelude(A, G, K, C/B, D, U, W) :-
    head_info(A, B, I, J, E, F),
    build_head(C, B, D, E, P),
    head_arg_matches(F, [], Q, H),
    lookup_passive_head(G, [A], H, R, L),
    gen_allocation(D, I, J, C/B, E, S),
    extend_id(D, N),
    extra_active_delegate_variables(A, K, H, M),
    append([L|E], M, O),
    build_head(C, B, N, O, T),
    V=(P:-Q, R, !, S, T),
    U=[V|W].
extra_active_delegate_variables(A, B, C, E) :-
    A=..[_|D],
    delegate_variables(A, B, C, D, E).
passive_delegate_variables(B, A, C, D, F) :-
    term_variables(A, E),
    delegate_variables(B, C, D, E, F).
delegate_variables(A, B, H, F, I) :-
    term_variables(A, C),
    term_variables(B, D),
    intersect_eq(C, D, E),
    list_difference_eq(E, F, G),
    translate(G, H, I).
simpagation_head2_worker(C, D, L, E, M, F, N, A, I, J, K, P) :-
    A=pragma(B, _, _, _, _),
    B=rule(_, _, G, H),
    simpagation_head2_worker_end(C,
                                 [D, E, F, G, H],
                                 I,
                                 J,
                                 K,
                                 O),
    simpagation_head2_worker_body(C,
                                  D,
                                  L,
                                  E,
                                  M,
                                  F,
                                  N,
                                  A,
                                  I,
                                  J,
                                  O,
                                  P).
simpagation_head2_worker_body(A, F, E2, G, Y, H, Z, D, P/B, Q, J2, K2) :-
    gen_var(L),
    gen_var(M),
    head_info(A, B, _, T1, N, C),
    head_arg_matches(C, [], _, K),
    D=pragma(E, _, F1, _, A1),
    E=rule(_, _, I, J),
    extra_active_delegate_variables(A,
                                    [F, G, H, I, J],
                                    K,
                                    O),
    append([[L|M]|N], O, R),
    build_head(P, B, Q, R, P1),
    functor(F, _, S),
    head_info(F, S, U, _, _, T),
    head_arg_matches(T, K, R1, G1),
    W=..[suspension, _, V, _, _, _, _|U],
    create_get_mutable_ref(active, V, X),
    Q1=(L=W, X),
    (   (   G\==[]
        ;   H\==[]
        )
    ->  append(G, H, B1),
        append(Y, Z, C1),
        reorder_heads(A1,
                      F-A,
                      B1,
                      C1,
                      D1,
                      E1),
        rest_heads_retrieval_and_matching(D1,
                                          E1,
                                          F1,
                                          [F, A],
                                          I1,
                                          H1,
                                          G1,
                                          L1,
                                          [F],
                                          [L],
                                          []),
        split_by_ids(E1, H1, Y, J1, K1)
    ;   I1=[],
        J1=[],
        K1=[],
        L1=G1
    ),
    gen_uncond_susps_detachments([L|J1],
                                 [F|G],
                                 H2),
    append([M|N], O, M1),
    build_head(P, B, Q, M1, U1),
    append([[]|N], O, N1),
    build_head(P, B, Q, N1, W1),
    guard_body_copies2(E, L1, O1, S1),
    guard_via_reschedule(I1,
                         O1,
                         v(P1, Q1, R1),
                         G2),
    (   S1\==true
    ->  gen_uncond_attach_goal(P/B, T1, X1, V1),
        gen_state_cond_call(T1, B, U1, V1, Y1),
        gen_state_cond_call(T1, B, W1, V1, Z1)
    ;   X1=true,
        Y1=U1,
        Z1=W1
    ),
    (   chr_pp_flag(debugable, on)
    ->  my_term_copy(I-J, L1, _, A2-B2),
        C2='chr debug_event'(try([L|J1], [T1|K1], A2, B2)),
        D2='chr debug_event'(apply([L|J1], [T1|K1], A2, B2))
    ;   C2=true,
        D2=true
    ),
    (   member(unique(E2, F2), F1),
        check_unique_keys(F2, K)
    ->  I2=(P1:-Q1, R1->(G2, C2->D2, H2, X1, S1, Z1;W1);U1)
    ;   I2=(P1:-Q1, R1, G2, C2->D2, H2, X1, S1, Y1;U1)
    ),
    J2=[I2|K2].
gen_state_cond_call(G, A, K, D, F) :-
    length(B, A),
    H=..[suspension, _, C, _, E, _, _|B],
    create_get_mutable_ref(active, C, I),
    create_get_mutable_ref(D, E, J),
    F=(G=H, I, J->'chr update_mutable'(inactive, C), K;true).
simpagation_head2_worker_end(A, D, H/B, I, N, P) :-
    head_info(A, B, _, _, F, C),
    head_arg_matches(C, [], _, E),
    extra_active_delegate_variables(A, D, E, G),
    append([[]|F], G, J),
    build_head(H, B, I, J, L),
    next_id(I, K),
    build_head(H, B, K, F, M),
    O=(L:-M),
    N=[O|P].
propagation_code(B, A, C, D, I, E, F, G, H) :-
    (   A==[]
    ->  propagation_single_headed(B,
                                  C,
                                  D,
                                  E,
                                  F,
                                  G,
                                  H)
    ;   propagation_multi_headed(B,
                                 A,
                                 C,
                                 D,
                                 I,
                                 E,
                                 F,
                                 G,
                                 H)
    ).
propagation_single_headed(A, I, X, C/B, D, C1, E1) :-
    head_info(A, B, K, L, E, H),
    build_head(C, B, D, E, U),
    inc_id(D, F),
    build_head(C, B, F, E, G),
    M=G,
    head_arg_matches(H, [], V, J),
    guard_body_copies(I, J, Y, A1),
    gen_allocation(D,
                   K,
                   L,
                   C/B,
                   E,
                   W),
    gen_uncond_attach_goal(C/B, L, Z, N),
    gen_state_cond_call(L, B, M, N, B1),
    (   chr_pp_flag(debugable, on)
    ->  I=rule(_, _, O, P),
        my_term_copy(O-P, J, _, Q-R),
        S='chr debug_event'(try([], [L], Q, R)),
        T='chr debug_event'(apply([], [L], Q, R))
    ;   S=true,
        T=true
    ),
    D1=(U:-V, W, 'chr novel_production'(L, X), Y, S, !, T, 'chr extend_history'(L, X), Z, A1, B1),
    C1=[D1|E1].
propagation_multi_headed(B, A, C, I, J, D, E, F, M) :-
    A=[H|G],
    propagation_prelude(B,
                        A,
                        C,
                        D,
                        E,
                        F,
                        L),
    extend_id(E, K),
    propagation_nested_code(G,
                            [H, B],
                            C,
                            I,
                            J,
                            D,
                            K,
                            L,
                            M).
propagation_prelude(A, [H|I], G, C/B, D, Y, A1) :-
    head_info(A, B, M, N, E, F),
    build_head(C, B, D, E, T),
    head_arg_matches(F, [], U, L),
    G=rule(_, _, J, K),
    extra_active_delegate_variables(A,
                                    [H, I, J, K],
                                    L,
                                    P),
    lookup_passive_head(H, [A], L, V, O),
    gen_allocation(D,
                   M,
                   N,
                   C/B,
                   E,
                   W),
    extend_id(D, Q),
    append([O|E], P, R),
    build_head(C, B, Q, R, S),
    X=S,
    Z=(T:-U, V, !, W, X),
    Y=[Z|A1].
propagation_nested_code([], [A|B], C, G, H, D, E, F, J) :-
    propagation_end([A|B],
                    [],
                    C,
                    D,
                    E,
                    F,
                    I),
    propagation_body(A,
                     B,
                     C,
                     G,
                     H,
                     D,
                     E,
                     I,
                     J).
propagation_nested_code([B|C], A, D, I, J, E, F, G, M) :-
    propagation_end(A,
                    [B|C],
                    D,
                    E,
                    F,
                    G,
                    H),
    propagation_accumulator([B|C],
                            A,
                            D,
                            E,
                            F,
                            H,
                            L),
    inc_id(F, K),
    propagation_nested_code(C,
                            [B|A],
                            D,
                            I,
                            J,
                            E,
                            K,
                            L,
                            M).
propagation_body(C, B, A, G1, B1, N/O, P, W1, Y1) :-
    A=rule(_, _, D, E),
    get_prop_inner_loop_vars(B,
                             [C, D, E],
                             M,
                             V,
                             Y,
                             W),
    gen_var(I),
    gen_var(L),
    functor(C, _, F),
    gen_vars(F, G),
    J=..[suspension, _, H, _, _, _, _|G],
    create_get_mutable_ref(active, H, K),
    M1=(I=J, K),
    Q=[[I|L]|M],
    build_head(N, O, P, Q, L1),
    R=[L|M],
    build_head(N, O, P, R, S),
    Z=S,
    C=..[_|T],
    pairup(T, G, U),
    head_arg_matches(U, V, O1, X),
    different_from_other_susps(C, I, B, W, N1),
    guard_body_copies(A, X, S1, U1),
    gen_uncond_attach_goal(N/O, Y, T1, A1),
    gen_state_cond_call(Y, O, Z, A1, V1),
    history_susps(B1, [I|W], Y, [], D1),
    bagof('chr novel_production'(C1, E1),
          (member(C1, D1), E1=P1),
          F1),
    list2conj(F1, R1),
    Q1=..[t, G1|D1],
    (   chr_pp_flag(debugable, on)
    ->  A=rule(_, _, D, E),
        my_term_copy(D-E, X, _, H1-I1),
        J1='chr debug_event'(try([], [Y, I|W], H1, I1)),
        K1='chr debug_event'(apply([], [Y, I|W], H1, I1))
    ;   J1=true,
        K1=true
    ),
    X1=(L1:-M1, N1, O1, P1=Q1, R1, S1, J1->K1, 'chr extend_history'(Y, P1), T1, U1, V1;Z),
    W1=[X1|Y1].
history_susps(A, B, D, E, F) :-
    (   A==0
    ->  reverse(B, C),
        append(C, [D|E], F)
    ;   B=[I|H],
        G is A-1,
        history_susps(G, H, D, [I|E], F)
    ).
get_prop_inner_loop_vars([A], F, I, E, C, []) :-
    !,
    functor(A, _, B),
    head_info(A, B, _, C, G, D),
    head_arg_matches(D, [], _, E),
    extra_active_delegate_variables(A, F, E, H),
    append(G, H, I).
get_prop_inner_loop_vars([B|A], C, N, J, D, [G|E]) :-
    get_prop_inner_loop_vars(A,
                             [B|C],
                             M,
                             I,
                             D,
                             E),
    functor(B, _, F),
    gen_var(L),
    head_info(B, F, _, G, _, H),
    head_arg_matches(H, I, _, J),
    passive_delegate_variables(B, A, C, J, K),
    append(K, [G, L|M], N).
propagation_end([C|B], D, A, H/I, J, S, U) :-
    A=rule(_, _, E, F),
    gen_var_susp_list_for(B,
                          [C, D, E, F],
                          _,
                          G,
                          L,
                          O),
    K=[[]|G],
    build_head(H, I, J, K, Q),
    (   J=[0|_]
    ->  next_id(J, M),
        N=L
    ;   dec_id(J, M),
        N=[O|L]
    ),
    build_head(H, I, M, N, P),
    R=P,
    T=(Q:-R),
    S=[T|U].
gen_var_susp_list_for([A], G, F, I, D, C) :-
    !,
    functor(A, _, B),
    head_info(A, B, _, C, D, E),
    head_arg_matches(E, [], _, F),
    extra_active_delegate_variables(A, G, F, H),
    append(D, H, I).
gen_var_susp_list_for([B|A], C, I, L, D, E) :-
    gen_var_susp_list_for(A,
                          [B|C],
                          H,
                          D,
                          _,
                          _),
    functor(B, _, F),
    gen_var(E),
    head_info(B, F, _, K, _, G),
    head_arg_matches(G, H, _, I),
    passive_delegate_variables(B, A, C, I, J),
    append(J, [K, E|D], L).
propagation_accumulator([D|E], [C|B], A, W/X, T, J1, L1) :-
    A=rule(_, _, F, G),
    pre_vars_and_susps(B,
                       [C, D, E, F, G],
                       V,
                       K,
                       M),
    gen_var(U),
    functor(C, _, H),
    gen_vars(H, I),
    head_info(C, H, I, L, _, J),
    head_arg_matches(J, K, R, S),
    O=..[suspension, _, N, _, _, _, _|I],
    different_from_other_susps(C, L, B, M, Q),
    create_get_mutable_ref(active, N, P),
    F1=(L=O, P, Q, R),
    lookup_passive_head(D, [C|B], S, G1, Z),
    inc_id(T, B1),
    Y=[[L|U]|V],
    build_head(W, X, T, Y, E1),
    passive_delegate_variables(C,
                               B,
                               [D, E, F, G],
                               S,
                               A1),
    append([Z|A1], [L, U|V], C1),
    build_head(W, X, B1, C1, H1),
    D1=[U|V],
    build_head(W, X, T, D1, I1),
    K1=(E1:-F1, G1->H1;I1),
    J1=[K1|L1].
pre_vars_and_susps([A], E, H, D, []) :-
    !,
    functor(A, _, B),
    head_info(A, B, _, _, F, C),
    head_arg_matches(C, [], _, D),
    extra_active_delegate_variables(A, E, D, G),
    append(F, G, H).
pre_vars_and_susps([B|A], C, M, I, [F|D]) :-
    pre_vars_and_susps(A, [B|C], L, H, D),
    functor(B, _, E),
    gen_var(K),
    head_info(B, E, _, F, _, G),
    head_arg_matches(G, H, _, I),
    passive_delegate_variables(B, A, C, I, J),
    append(J, [F, K|L], M).
reorder_heads(A, B, C, D, E, F) :-
    (   chr_pp_flag(reorder_heads, on)
    ->  reorder_heads_main(A, B, C, D, E, F)
    ;   E=C,
        F=D
    ).
reorder_heads_main(E, A, C, D, M, O) :-
    term_variables(A, B),
    F=entry([], [], B, C, D, E),
    a_star(F,
           G^(chr_translate:final_data(G)),
           H^I^J^(chr_translate:expand_data(H, I, J)),
           K),
    K=entry(L, N, _, _, _, _),
    reverse(L, M),
    reverse(N, O).
final_data(A) :-
    A=entry(_, _, _, _, [], _).
expand_data(A, B, M) :-
    A=entry(C, D, L, H, I, E),
    term_variables(A, _),
    B=entry([F|C], [G|D], N, J, K, E),
    select2(F, G, H, I, J, K),
    order_score(F, G, L, J, E, M),
    term_variables([F|L], N).
order_score(A, E, F, G, H, I) :-
    functor(A, B, C),
    get_store_type(B/C, D),
    order_score(D, A, E, F, G, H, I).
order_score(default, A, _, D, B, _, E) :-
    term_variables(A, C),
    term_variables(B, _),
    order_score_vars(C, D, B, 0, E).
order_score(multi_hash(A), B, _, C, _, _, D) :-
    order_score_indexes(A, B, C, 0, D).
order_score(global_ground, A, C, _, _, B, E) :-
    functor(A, _, F),
    (   get_pragma_unique(B, C, D),
        D==[]
    ->  E=1
    ;   F==0
    ->  E=10
    ;   F>0
    ->  E=100
    ).
order_score(multi_store(D), A, F, B, C, G, J) :-
    find_with_var_identity(H,
                           t(A, B, C),
                           (member(E, D), chr_translate:order_score(E, A, F, B, C, G, H)),
                           I),
    min_list(I, J).
order_score_indexes([], _, _, A, A) :-
    A>0.
order_score_indexes([A|H], B, E, F, I) :-
    multi_hash_key_args(A, B, C),
    (   forall(D, C, hprolog:memberchk_eq(D, E))
    ->  G is F+10
    ;   G=F
    ),
    order_score_indexes(H, B, E, G, I).
order_score_vars([], _, _, A, B) :-
    (   A==0
    ->  B=0
    ;   B=A
    ).
order_score_vars([A|F], B, D, C, G) :-
    (   memberchk_eq(A, B)
    ->  E is C+10
    ;   memberchk_eq(A, D)
    ->  E is C+100
    ;   E=C
    ),
    order_score_vars(F, B, D, E, G).
create_get_mutable_ref(C, B, A) :-
    A=(B=mutable(C)).
gen_var(_).
gen_vars(B, A) :-
    length(A, B).
head_info(E, A, B, C, D, G) :-
    vars_susp(A, B, C, D),
    E=..[_|F],
    pairup(F, B, G).
inc_id([C|A], [B|A]) :-
    B is C+1.
dec_id([C|A], [B|A]) :-
    B is C-1.
extend_id(A, [0|A]).
next_id([_, C|A], [B|A]) :-
    B is C+1.
build_head(A, B, C, F, D) :-
    buildName(A, B, C, E),
    D=..[E|F].
buildName(A, C, D, F) :-
    atom_concat(A, /, B),
    atomic_concat(B, C, E),
    buildName_(D, E, F).
buildName_([], A, A).
buildName_([E|A], B, F) :-
    buildName_(A, B, C),
    atom_concat(C, '__', D),
    atomic_concat(D, E, F).
vars_susp(B, A, C, D) :-
    length(A, B),
    append(A, [C], D).
make_attr(B, D, A, C) :-
    length(A, B),
    C=..[v, D|A].
or_pattern(A, B) :-
    C is A-1,
    B is 1<<C.
and_pattern(A, C) :-
    B is A-1,
    D is 1<<B,
    C is -1*(D+1).
conj2list(A, B) :-
    conj2list(A, B, []).
conj2list(A, C, F) :-
    A=(B, D),
    !,
    conj2list(B, C, E),
    conj2list(D, E, F).
conj2list(A, [A|B], B).
list2conj([], true).
list2conj([B], A) :-
    !,
    A=B.
list2conj([A|B], C) :-
    (   A==true
    ->  list2conj(B, C)
    ;   C=(A, D),
        list2conj(B, D)
    ).
list2disj([], fail).
list2disj([B], A) :-
    !,
    A=B.
list2disj([A|B], C) :-
    (   A==fail
    ->  list2disj(B, C)
    ;   C=(A;D),
        list2disj(B, D)
    ).
atom_concat_list([A], A) :-
    !.
atom_concat_list([B|A], D) :-
    atom_concat_list(A, C),
    atomic_concat(B, C, D).
make_name(A, B/C, D) :-
    atom_concat_list([A, B, /, C], D).
set_elems([], _).
set_elems([A|B], A) :-
    set_elems(B, A).
member2([A|_], [B|_], A-B).
member2([_|A], [_|B], C) :-
    member2(A, B, C).
select2(A, B, [A|C], [B|D], C, D).
select2(C, D, [A|E], [B|F], [A|G], [B|H]) :-
    select2(C, D, E, F, G, H).
pair_all_with([], _, []).
pair_all_with([A|C], B, [A-B|D]) :-
    pair_all_with(C, B, D).
lookup_passive_head(A, E, F, G, H) :-
    functor(A, B, C),
    get_store_type(B/C, D),
    lookup_passive_head(D, A, E, F, G, H).
lookup_passive_head(default, A, B, C, D, G) :-
    passive_head_via(A, B, [], C, D, H, E),
    instantiate_pattern_goals(E),
    get_max_constraint_index(F),
    (   F==1
    ->  G=H
    ;   functor(A, I, J),
        get_constraint_index(I/J, K),
        make_attr(F, _, L, H),
        nth1(K, L, G)
    ).
lookup_passive_head(multi_hash(A), C, _, E, J, L) :-
    once(( member(B, A),
           multi_hash_key_args(B, C, D),
           translate(D, E, F)
         )),
    (   F=[G]
    ->  true
    ;   G=..[k|F]
    ),
    functor(C, H, I),
    multi_hash_via_lookup_name(H/I, B, K),
    J=..[K, G, L],
    update_store_type(H/I, multi_hash([B])).
lookup_passive_head(global_ground, A, _, _, F, E) :-
    functor(A, B, C),
    global_ground_store_name(B/C, D),
    make_get_store_goal(D, E, F),
    update_store_type(B/C, global_ground).
lookup_passive_head(multi_store(A), C, D, E, F, G) :-
    once(( member(B, A),
           lookup_passive_head(B,
                               C,
                               D,
                               E,
                               F,
                               G)
         )).
assume_constraint_stores([]).
assume_constraint_stores([A|E]) :-
    (   \+ may_trigger(A),
        is_attached(A),
        get_store_type(A, default)
    ->  get_indexed_arguments(A, C),
        findall(B,
                ( sublist(B, C),
                  B\==[]
                ),
                D),
        assumed_store_type(A,
                           multi_store([multi_hash(D), global_ground]))
    ;   true
    ),
    assume_constraint_stores(E).
get_indexed_arguments(A, C) :-
    A=_/B,
    get_indexed_arguments(1, B, A, C).
get_indexed_arguments(A, B, D, C) :-
    (   A>B
    ->  C=[]
    ;   (   is_indexed_argument(D, A)
        ->  C=[A|E]
        ;   C=E
        ),
        F is A+1,
        get_indexed_arguments(F, B, D, E)
    ).
validate_store_type_assumptions([]).
validate_store_type_assumptions([A|B]) :-
    validate_store_type_assumption(A),
    validate_store_type_assumptions(B).
verbosity_on :-
    prolog_flag(verbose, A),
    A==yes.
attr_unify_hook(_, _) :-
    write('ERROR: Unexpected triggering of attr_unify_hook/2 in module '),
    writeln(chr_translate).
remove_constraint_internal(A, D, E) :-
    arg(2, A, B),
    'chr get_mutable'(C, B),
    'chr update_mutable'(removed, B),
    (   compound(C)
    ->  D=[],
        E=no
    ;   C==removed
    ->  D=[],
        E=no
    ;   E=yes,
        chr_indexed_variables(A, D)
    ).
activate_constraint(H, G, A, C) :-
    arg(2, A, B),
    'chr get_mutable'(F, B),
    'chr update_mutable'(active, B),
    (   nonvar(C)
    ->  true
    ;   arg(4, A, D),
        'chr get_mutable'(E, D),
        C is E+1,
        'chr update_mutable'(C, D)
    ),
    (   compound(F)
    ->  term_variables(F, G),
        'chr none_locked'(G),
        H=yes
    ;   F==removed
    ->  chr_indexed_variables(A, G),
        H=yes
    ;   G=[],
        H=no
    ).
allocate_constraint(B, A, C, D) :-
    A=..[suspension, J, I, B, E, G, C|D],
    'chr create_mutable'(0, E),
    'chr empty_history'(F),
    'chr create_mutable'(F, G),
    chr_indexed_variables(A, H),
    'chr create_mutable'(passive(H), I),
    'chr gen_id'(J).
chr_indexed_variables(_, []).
insert_constraint_internal(yes, E, A, B, C, D) :-
    A=..[suspension, J, F, B, G, I, C|D],
    chr_indexed_variables(A, E),
    'chr none_locked'(E),
    'chr create_mutable'(active, F),
    'chr create_mutable'(0, G),
    'chr empty_history'(H),
    'chr create_mutable'(H, I),
    'chr gen_id'(J).
'$insert_in_store_constraint/2'(A) :-
    ( arg(8, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:constraint/2-2', B),
      insert_ht(B, C, A)
    ),
    true.
'$delete_from_store_constraint/2'(A) :-
    ( arg(8, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:constraint/2-2', B),
      delete_ht(B, C, A)
    ),
    true.
'$insert_in_store_constraint_count/1'(A) :-
    nb_getval('$chr_store_global_ground_chr_translate:constraint_count/1',
              B),
    b_setval('$chr_store_global_ground_chr_translate:constraint_count/1',
             [A|B]).
'$delete_from_store_constraint_count/1'(B) :-
    nb_getval('$chr_store_global_ground_chr_translate:constraint_count/1',
              A),
    'chr sbag_del_element'(A, B, C),
    b_setval('$chr_store_global_ground_chr_translate:constraint_count/1',
             C).
'$insert_in_store_constraint_index/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:constraint_index/2-1',
                B),
      insert_ht(B, C, A)
    ),
    true.
'$delete_from_store_constraint_index/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:constraint_index/2-1',
                B),
      delete_ht(B, C, A)
    ),
    true.
'$insert_in_store_max_constraint_index/1'(A) :-
    nb_getval('$chr_store_global_ground_chr_translate:max_constraint_index/1',
              B),
    b_setval('$chr_store_global_ground_chr_translate:max_constraint_index/1',
             [A|B]).
'$delete_from_store_max_constraint_index/1'(B) :-
    nb_getval('$chr_store_global_ground_chr_translate:max_constraint_index/1',
              A),
    'chr sbag_del_element'(A, B, C),
    b_setval('$chr_store_global_ground_chr_translate:max_constraint_index/1',
             C).
'$insert_in_store_target_module/1'(A) :-
    nb_getval('$chr_store_global_ground_chr_translate:target_module/1', B),
    b_setval('$chr_store_global_ground_chr_translate:target_module/1',
             [A|B]).
'$delete_from_store_target_module/1'(B) :-
    nb_getval('$chr_store_global_ground_chr_translate:target_module/1', A),
    'chr sbag_del_element'(A, B, C),
    b_setval('$chr_store_global_ground_chr_translate:target_module/1', C).
'$insert_in_store_attached/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:attached/2-1', B),
      insert_ht(B, C, A)
    ),
    true.
'$delete_from_store_attached/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:attached/2-1', B),
      delete_ht(B, C, A)
    ),
    true.
'$insert_in_store_indexed_argument/2'(A) :-
    ( ( arg(7, A, C),
        arg(8, A, D)
      ),
      nb_getval('$chr_store_multi_hash_chr_translate:indexed_argument/2-12',
                B),
      insert_ht(B, k(C, D), A)
    ),
    true.
'$delete_from_store_indexed_argument/2'(A) :-
    ( ( arg(7, A, C),
        arg(8, A, D)
      ),
      nb_getval('$chr_store_multi_hash_chr_translate:indexed_argument/2-12',
                B),
      delete_ht(B, k(C, D), A)
    ),
    true.
'$insert_in_store_constraint_mode/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:constraint_mode/2-1',
                B),
      insert_ht(B, C, A)
    ),
    true.
'$delete_from_store_constraint_mode/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:constraint_mode/2-1',
                B),
      delete_ht(B, C, A)
    ),
    true.
'$insert_in_store_store_type/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:store_type/2-1', B),
      insert_ht(B, C, A)
    ),
    true.
'$delete_from_store_store_type/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:store_type/2-1', B),
      delete_ht(B, C, A)
    ),
    true.
'$insert_in_store_actual_store_types/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:actual_store_types/2-1',
                B),
      insert_ht(B, C, A)
    ),
    true.
'$delete_from_store_actual_store_types/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:actual_store_types/2-1',
                B),
      delete_ht(B, C, A)
    ),
    true.
'$insert_in_store_assumed_store_type/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:assumed_store_type/2-1',
                B),
      insert_ht(B, C, A)
    ),
    true.
'$delete_from_store_assumed_store_type/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:assumed_store_type/2-1',
                B),
      delete_ht(B, C, A)
    ),
    true.
'$insert_in_store_rule_count/1'(A) :-
    nb_getval('$chr_store_global_ground_chr_translate:rule_count/1', B),
    b_setval('$chr_store_global_ground_chr_translate:rule_count/1',
             [A|B]).
'$delete_from_store_rule_count/1'(B) :-
    nb_getval('$chr_store_global_ground_chr_translate:rule_count/1', A),
    'chr sbag_del_element'(A, B, C),
    b_setval('$chr_store_global_ground_chr_translate:rule_count/1', C).
'$insert_in_store_passive/2'(A) :-
    ( ( arg(7, A, C),
        nb_getval('$chr_store_multi_hash_chr_translate:passive/2-1', B),
        insert_ht(B, C, A)
      ),
      true
    ),
    ( ( arg(7, A, E),
        arg(8, A, F)
      ),
      nb_getval('$chr_store_multi_hash_chr_translate:passive/2-12', D),
      insert_ht(D, k(E, F), A)
    ),
    true.
'$delete_from_store_passive/2'(A) :-
    ( ( arg(7, A, C),
        nb_getval('$chr_store_multi_hash_chr_translate:passive/2-1', B),
        delete_ht(B, C, A)
      ),
      true
    ),
    ( ( arg(7, A, E),
        arg(8, A, F)
      ),
      nb_getval('$chr_store_multi_hash_chr_translate:passive/2-12', D),
      delete_ht(D, k(E, F), A)
    ),
    true.
'$insert_in_store_pragma_unique/3'(A) :-
    ( ( arg(7, A, C),
        arg(8, A, D)
      ),
      nb_getval('$chr_store_multi_hash_chr_translate:pragma_unique/3-12',
                B),
      insert_ht(B, k(C, D), A)
    ),
    true.
'$delete_from_store_pragma_unique/3'(A) :-
    ( ( arg(7, A, C),
        arg(8, A, D)
      ),
      nb_getval('$chr_store_multi_hash_chr_translate:pragma_unique/3-12',
                B),
      delete_ht(B, k(C, D), A)
    ),
    true.
'$insert_in_store_occurrence/4'(A) :-
    ( ( arg(9, A, C),
        nb_getval('$chr_store_multi_hash_chr_translate:occurrence/4-3', B),
        insert_ht(B, C, A)
      ),
      true
    ),
    ( ( arg(8, A, E),
        nb_getval('$chr_store_multi_hash_chr_translate:occurrence/4-2', D),
        insert_ht(D, E, A)
      ),
      true
    ),
    ( ( arg(7, A, G),
        arg(8, A, H),
        arg(9, A, I),
        arg(10, A, J)
      ),
      nb_getval('$chr_store_multi_hash_chr_translate:occurrence/4-1234', F),
      insert_ht(F, k(G, H, I, J), A)
    ),
    true.
'$delete_from_store_occurrence/4'(A) :-
    ( ( arg(9, A, C),
        nb_getval('$chr_store_multi_hash_chr_translate:occurrence/4-3', B),
        delete_ht(B, C, A)
      ),
      true
    ),
    ( ( arg(8, A, E),
        nb_getval('$chr_store_multi_hash_chr_translate:occurrence/4-2', D),
        delete_ht(D, E, A)
      ),
      true
    ),
    ( ( arg(7, A, G),
        arg(8, A, H),
        arg(9, A, I),
        arg(10, A, J)
      ),
      nb_getval('$chr_store_multi_hash_chr_translate:occurrence/4-1234', F),
      delete_ht(F, k(G, H, I, J), A)
    ),
    true.
'$insert_in_store_max_occurrence/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:max_occurrence/2-1',
                B),
      insert_ht(B, C, A)
    ),
    true.
'$delete_from_store_max_occurrence/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:max_occurrence/2-1',
                B),
      delete_ht(B, C, A)
    ),
    true.
'$insert_in_store_allocation_occurrence/2'(A) :-
    ( ( arg(7, A, C),
        nb_getval('$chr_store_multi_hash_chr_translate:allocation_occurrence/2-1',
                  B),
        insert_ht(B, C, A)
      ),
      true
    ),
    ( ( ( arg(7, A, E),
          arg(8, A, F)
        ),
        nb_getval('$chr_store_multi_hash_chr_translate:allocation_occurrence/2-12',
                  D),
        insert_ht(D, k(E, F), A)
      ),
      true
    ),
    nb_getval('$chr_store_global_ground_chr_translate:allocation_occurrence/2',
              G),
    b_setval('$chr_store_global_ground_chr_translate:allocation_occurrence/2',
             [A|G]).
'$delete_from_store_allocation_occurrence/2'(A) :-
    ( ( arg(7, A, C),
        nb_getval('$chr_store_multi_hash_chr_translate:allocation_occurrence/2-1',
                  B),
        delete_ht(B, C, A)
      ),
      true
    ),
    ( ( ( arg(7, A, E),
          arg(8, A, F)
        ),
        nb_getval('$chr_store_multi_hash_chr_translate:allocation_occurrence/2-12',
                  D),
        delete_ht(D, k(E, F), A)
      ),
      true
    ),
    nb_getval('$chr_store_global_ground_chr_translate:allocation_occurrence/2',
              G),
    'chr sbag_del_element'(G, A, H),
    b_setval('$chr_store_global_ground_chr_translate:allocation_occurrence/2',
             H).
'$insert_in_store_rule/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:rule/2-1', B),
      insert_ht(B, C, A)
    ),
    true.
'$delete_from_store_rule/2'(A) :-
    ( arg(7, A, C),
      nb_getval('$chr_store_multi_hash_chr_translate:rule/2-1', B),
      delete_ht(B, C, A)
    ),
    true.
'$enumerate_suspensions'(B) :-
    (   nb_getval('$chr_store_multi_hash_chr_translate:constraint/2-2', A),
        value_ht(A, B)
    ;   nb_getval('$chr_store_global_ground_chr_translate:constraint_count/1',
                  C),
        member(B, C)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:constraint_index/2-1',
                  D),
        value_ht(D, B)
    ;   nb_getval('$chr_store_global_ground_chr_translate:max_constraint_index/1',
                  E),
        member(B, E)
    ;   nb_getval('$chr_store_global_ground_chr_translate:target_module/1',
                  F),
        member(B, F)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:attached/2-1', G),
        value_ht(G, B)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:indexed_argument/2-12',
                  H),
        value_ht(H, B)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:constraint_mode/2-1',
                  I),
        value_ht(I, B)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:store_type/2-1', J),
        value_ht(J, B)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:actual_store_types/2-1',
                  K),
        value_ht(K, B)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:assumed_store_type/2-1',
                  L),
        value_ht(L, B)
    ;   nb_getval('$chr_store_global_ground_chr_translate:rule_count/1',
                  M),
        member(B, M)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:passive/2-1', N),
        value_ht(N, B)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:pragma_unique/3-12',
                  O),
        value_ht(O, B)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:occurrence/4-3', P),
        value_ht(P, B)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:max_occurrence/2-1',
                  Q),
        value_ht(Q, B)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:allocation_occurrence/2-1',
                  R),
        value_ht(R, B)
    ;   nb_getval('$chr_store_multi_hash_chr_translate:rule/2-1', S),
        value_ht(S, B)
    ).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:constraint/2-2', A).
'$via1_multi_hash_constraint/2-2'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:constraint/2-2', A),
    lookup_ht(A, B, C).
:- nb_setval('$chr_store_global_ground_chr_translate:constraint_count/1', []).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:constraint_index/2-1', A).
'$via1_multi_hash_constraint_index/2-1'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:constraint_index/2-1',
              A),
    lookup_ht(A, B, C).
:- nb_setval('$chr_store_global_ground_chr_translate:max_constraint_index/1', []).
:- nb_setval('$chr_store_global_ground_chr_translate:target_module/1', []).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:attached/2-1', A).
'$via1_multi_hash_attached/2-1'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:attached/2-1', A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:indexed_argument/2-12',
             A).
'$via1_multi_hash_indexed_argument/2-12'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:indexed_argument/2-12',
              A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:constraint_mode/2-1', A).
'$via1_multi_hash_constraint_mode/2-1'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:constraint_mode/2-1', A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:store_type/2-1', A).
'$via1_multi_hash_store_type/2-1'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:store_type/2-1', A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:actual_store_types/2-1',
             A).
'$via1_multi_hash_actual_store_types/2-1'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:actual_store_types/2-1',
              A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:assumed_store_type/2-1',
             A).
'$via1_multi_hash_assumed_store_type/2-1'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:assumed_store_type/2-1',
              A),
    lookup_ht(A, B, C).
:- nb_setval('$chr_store_global_ground_chr_translate:rule_count/1', []).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:passive/2-1', A).
'$via1_multi_hash_passive/2-1'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:passive/2-1', A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:passive/2-12', A).
'$via1_multi_hash_passive/2-12'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:passive/2-12', A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:pragma_unique/3-12', A).
'$via1_multi_hash_pragma_unique/3-12'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:pragma_unique/3-12', A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:occurrence/4-3', A).
'$via1_multi_hash_occurrence/4-3'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:occurrence/4-3', A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:occurrence/4-2', A).
'$via1_multi_hash_occurrence/4-2'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:occurrence/4-2', A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:occurrence/4-1234', A).
'$via1_multi_hash_occurrence/4-1234'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:occurrence/4-1234', A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:max_occurrence/2-1', A).
'$via1_multi_hash_max_occurrence/2-1'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:max_occurrence/2-1', A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:allocation_occurrence/2-1',
             A).
'$via1_multi_hash_allocation_occurrence/2-1'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:allocation_occurrence/2-1',
              A),
    lookup_ht(A, B, C).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:allocation_occurrence/2-12',
             A).
'$via1_multi_hash_allocation_occurrence/2-12'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:allocation_occurrence/2-12',
              A),
    lookup_ht(A, B, C).
:- nb_setval('$chr_store_global_ground_chr_translate:allocation_occurrence/2',
             []).
:- new_ht(A),
   nb_setval('$chr_store_multi_hash_chr_translate:rule/2-1', A).
'$via1_multi_hash_rule/2-1'(B, C) :-
    nb_getval('$chr_store_multi_hash_chr_translate:rule/2-1', A),
    lookup_ht(A, B, C).
constraint(A, B) :-
    'constraint/2__0'(A, B, _).
'constraint/2__0'(B, C, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'constraint/2__0'(B, C, A),
                               constraint(B, C),
                               [B, C]),
    '$insert_in_store_constraint/2'(A).
get_constraint(A, B) :-
    'get_constraint/2__0'(A, B, _).
'get_constraint/2__0'(F, A, _) :-
    '$via1_multi_hash_constraint/2-2'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, G, E),
    D=mutable(active),
    E==A,
    !,
    F=G.
'get_constraint/2__0'(_, _, _) :-
    !,
    fail.
constraint_count(A) :-
    'constraint_count/1__0'(A, _).
'constraint_count/1__0'(B, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'constraint_count/1__0'(B, A),
                               constraint_count(B),
                               [B]),
    '$insert_in_store_constraint_count/1'(A).
get_constraint_count(A) :-
    'get_constraint_count/1__0'(A, _).
'get_constraint_count/1__0'(D, _) :-
    nb_getval('$chr_store_global_ground_chr_translate:constraint_count/1',
              A),
    member(B, A),
    B=suspension(_, C, _, _, _, _, E),
    C=mutable(active),
    !,
    D=E.
'get_constraint_count/1__0'(A, _) :-
    !,
    A=0.
constraint_index(A, B) :-
    'constraint_index/2__0'(A, B, _).
'constraint_index/2__0'(B, C, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'constraint_index/2__0'(B, C, A),
                               constraint_index(B, C),
                               [B, C]),
    '$insert_in_store_constraint_index/2'(A).
get_constraint_index(A, B) :-
    'get_constraint_index/2__0'(A, B, _).
'get_constraint_index/2__0'(A, F, _) :-
    '$via1_multi_hash_constraint_index/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, G),
    D=mutable(active),
    E==A,
    !,
    F=G.
'get_constraint_index/2__0'(_, _, _) :-
    !,
    fail.
max_constraint_index(A) :-
    'max_constraint_index/1__0'(A, _).
'max_constraint_index/1__0'(B, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'max_constraint_index/1__0'(B, A),
                               max_constraint_index(B),
                               [B]),
    '$insert_in_store_max_constraint_index/1'(A).
get_max_constraint_index(A) :-
    'get_max_constraint_index/1__0'(A, _).
'get_max_constraint_index/1__0'(D, _) :-
    nb_getval('$chr_store_global_ground_chr_translate:max_constraint_index/1',
              A),
    member(B, A),
    B=suspension(_, C, _, _, _, _, E),
    C=mutable(active),
    !,
    D=E.
'get_max_constraint_index/1__0'(A, _) :-
    !,
    A=0.
target_module(A) :-
    'target_module/1__0'(A, _).
'target_module/1__0'(B, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'target_module/1__0'(B, A),
                               target_module(B),
                               [B]),
    '$insert_in_store_target_module/1'(A).
get_target_module(A) :-
    'get_target_module/1__0'(A, _).
'get_target_module/1__0'(D, _) :-
    nb_getval('$chr_store_global_ground_chr_translate:target_module/1', A),
    member(B, A),
    B=suspension(_, C, _, _, _, _, E),
    C=mutable(active),
    !,
    D=E.
'get_target_module/1__0'(A, _) :-
    !,
    A=user.
attached(A, B) :-
    'attached/2__0'(A, B, _).
'attached/2__0'(A, _, _) :-
    '$via1_multi_hash_attached/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, F),
    D=mutable(active),
    E==A,
    F==yes,
    !.
'attached/2__0'(B, A, C) :-
    A==yes,
    '$via1_multi_hash_attached/2-1'(B, D),
    !,
    allocate_constraint(chr_translate:'attached/2__0'(B, A, C),
                        C,
                        attached(B, A),
                        [B, A]),
    'attached/2__0__0'(D, B, A, C).
'attached/2__0__0'([], A, B, C) :-
    'attached/2__1'(A, B, C).
'attached/2__0__0'([A|F], D, G, H) :-
    (   ( A=suspension(_, B, _, _, _, _, C, _),
          B=mutable(active)
        ),
        C==D
    ->  ( remove_constraint_internal(A, _, E),
          (   E==yes
          ->  '$delete_from_store_attached/2'(A)
          ;   true
          )
        ),
        'attached/2__0__0'(F, D, G, H)
    ;   'attached/2__0__0'(F, D, G, H)
    ).
'attached/2__0'(A, B, C) :-
    allocate_constraint(chr_translate:'attached/2__0'(A, B, C),
                        C,
                        attached(A, B),
                        [A, B]),
    'attached/2__1'(A, B, C).
'attached/2__1'(A, _, G) :-
    '$via1_multi_hash_attached/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, F),
    D=mutable(active),
    E==A,
    F==no,
    !,
    (   var(G)
    ->  true
    ;   remove_constraint_internal(G, _, H),
        (   H==yes
        ->  '$delete_from_store_attached/2'(G)
        ;   true
        )
    ).
'attached/2__1'(B, A, D) :-
    A==no,
    '$via1_multi_hash_attached/2-1'(B, C),
    !,
    'attached/2__1__0'(C, B, A, D).
'attached/2__1__0'([], A, B, C) :-
    'attached/2__2'(A, B, C).
'attached/2__1__0'([A|F], D, G, H) :-
    (   ( A=suspension(_, B, _, _, _, _, C, _),
          B=mutable(active)
        ),
        C==D
    ->  ( remove_constraint_internal(A, _, E),
          (   E==yes
          ->  '$delete_from_store_attached/2'(A)
          ;   true
          )
        ),
        'attached/2__1__0'(F, D, G, H)
    ;   'attached/2__1__0'(F, D, G, H)
    ).
'attached/2__1'(A, B, C) :-
    'attached/2__2'(A, B, C).
'attached/2__2'(B, A, H) :-
    ( A==maybe,
      '$via1_multi_hash_attached/2-1'(B, C)
    ),
    (   member(D, C),
        D=suspension(_, E, _, _, _, _, F, G),
        E=mutable(active),
        F==B,
        G==maybe,
        !,
        (   var(H)
        ->  true
        ;   remove_constraint_internal(H, _, I),
            (   I==yes
            ->  '$delete_from_store_attached/2'(H)
            ;   true
            )
        )
    ;   !,
        'attached/2__2__0'(C, B, A, H)
    ).
'attached/2__2__0'([], A, B, C) :-
    'attached/2__3'(A, B, C).
'attached/2__2__0'([A|G], D, H, I) :-
    (   ( A=suspension(_, B, _, _, _, _, C, E),
          B=mutable(active)
        ),
        C==D,
        E==maybe
    ->  ( remove_constraint_internal(A, _, F),
          (   F==yes
          ->  '$delete_from_store_attached/2'(A)
          ;   true
          )
        ),
        'attached/2__2__0'(G, D, H, I)
    ;   'attached/2__2__0'(G, D, H, I)
    ).
'attached/2__2'(A, B, C) :-
    'attached/2__3'(A, B, C).
'attached/2__3'(_, _, A) :-
    activate_constraint(B, _, A, _),
    (   B==yes
    ->  '$insert_in_store_attached/2'(A)
    ;   true
    ).
is_attached(A) :-
    'is_attached/1__0'(A, _).
'is_attached/1__0'(A, _) :-
    '$via1_multi_hash_attached/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, F),
    D=mutable(active),
    E==A,
    !,
    F\==no.
'is_attached/1__0'(_, _) :-
    !.
indexed_argument(A, B) :-
    'indexed_argument/2__0'(A, B, _).
'indexed_argument/2__0'(A, B, H) :-
    '$via1_multi_hash_indexed_argument/2-12'(k(A, B), C),
    (   member(D, C),
        D=suspension(_, E, _, _, _, _, F, G),
        E=mutable(active),
        F==A,
        G==B,
        !
    ;   !,
        allocate_constraint(chr_translate:'indexed_argument/2__0'(A, B, H),
                            H,
                            indexed_argument(A, B),
                            [A, B]),
        'indexed_argument/2__0__0'(C, A, B, H)
    ).
'indexed_argument/2__0__0'([], A, B, C) :-
    'indexed_argument/2__1'(A, B, C).
'indexed_argument/2__0__0'([A|H], D, F, I) :-
    (   ( A=suspension(_, B, _, _, _, _, C, E),
          B=mutable(active)
        ),
        C==D,
        E==F
    ->  ( remove_constraint_internal(A, _, G),
          (   G==yes
          ->  '$delete_from_store_indexed_argument/2'(A)
          ;   true
          )
        ),
        'indexed_argument/2__0__0'(H, D, F, I)
    ;   'indexed_argument/2__0__0'(H, D, F, I)
    ).
'indexed_argument/2__0'(A, B, C) :-
    allocate_constraint(chr_translate:'indexed_argument/2__0'(A, B, C),
                        C,
                        indexed_argument(A, B),
                        [A, B]),
    'indexed_argument/2__1'(A, B, C).
'indexed_argument/2__1'(_, _, A) :-
    activate_constraint(B, _, A, _),
    (   B==yes
    ->  '$insert_in_store_indexed_argument/2'(A)
    ;   true
    ).
is_indexed_argument(A, B) :-
    'is_indexed_argument/2__0'(A, B, _).
'is_indexed_argument/2__0'(A, B, _) :-
    '$via1_multi_hash_indexed_argument/2-12'(k(A, B), C),
    member(D, C),
    D=suspension(_, E, _, _, _, _, F, G),
    E=mutable(active),
    F==A,
    G==B,
    !.
'is_indexed_argument/2__0'(_, _, _) :-
    !,
    fail.
constraint_mode(A, B) :-
    'constraint_mode/2__0'(A, B, _).
'constraint_mode/2__0'(B, C, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'constraint_mode/2__0'(B, C, A),
                               constraint_mode(B, C),
                               [B, C]),
    '$insert_in_store_constraint_mode/2'(A).
get_constraint_mode(A, B) :-
    'get_constraint_mode/2__0'(A, B, _).
'get_constraint_mode/2__0'(A, F, _) :-
    '$via1_multi_hash_constraint_mode/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, G),
    D=mutable(active),
    E==A,
    !,
    F=G.
'get_constraint_mode/2__0'(A, B, _) :-
    !,
    A=_/C,
    length(B, C),
    set_elems(B, ?).
may_trigger(A) :-
    'may_trigger/1__0'(A, _).
'may_trigger/1__0'(A, _) :-
    !,
    is_attached(A),
    get_constraint_mode(A, B),
    has_nonground_indexed_argument(A, 1, B).
has_nonground_indexed_argument(A, B, C) :-
    'has_nonground_indexed_argument/3__0'(A, B, C, _).
'has_nonground_indexed_argument/3__0'(B, C, A, _) :-
    nonvar(A),
    A=[D|F],
    !,
    (   is_indexed_argument(B, C),
        D\==(+)
    ->  true
    ;   E is C+1,
        has_nonground_indexed_argument(B, E, F)
    ).
'has_nonground_indexed_argument/3__0'(_, _, _, _) :-
    !,
    fail.
store_type(A, B) :-
    'store_type/2__0'(A, B, _).
'store_type/2__0'(B, A, _) :-
    nonvar(A),
    A=atom_hash(C),
    !,
    store_type(B, multi_hash([C])).
'store_type/2__0'(B, C, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'store_type/2__0'(B, C, A),
                               store_type(B, C),
                               [B, C]),
    '$insert_in_store_store_type/2'(A).
get_store_type(A, B) :-
    'get_store_type/2__0'(A, B, _).
'get_store_type/2__0'(A, F, _) :-
    '$via1_multi_hash_store_type/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, G),
    D=mutable(active),
    E==A,
    !,
    F=G.
'get_store_type/2__0'(A, F, _) :-
    '$via1_multi_hash_assumed_store_type/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, G),
    D=mutable(active),
    E==A,
    !,
    F=G.
'get_store_type/2__0'(_, A, _) :-
    !,
    A=default.
update_store_type(A, B) :-
    'update_store_type/2__0'(A, B, _).
'update_store_type/2__0'(A, F, _) :-
    ( '$via1_multi_hash_actual_store_types/2-1'(A, B),
      member(C, B),
      C=suspension(_, D, _, _, _, _, E, G),
      D=mutable(active),
      E==A
    ),
    (   'chr lock'(F),
        'chr lock'(G),
        member(F, G),
        'chr unlock'(F),
        'chr unlock'(G),
        !
    ;   !,
        remove_constraint_internal(C, _, H),
        (   H==yes
        ->  '$delete_from_store_actual_store_types/2'(C)
        ;   true
        ),
        actual_store_types(A, [F|G])
    ).
'update_store_type/2__0'(A, B, _) :-
    !,
    actual_store_types(A, [B]).
actual_store_types(A, B) :-
    'actual_store_types/2__0'(A, B, _).
'actual_store_types/2__0'(B, C, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'actual_store_types/2__0'(B, C, A),
                               actual_store_types(B, C),
                               [B, C]),
    '$insert_in_store_actual_store_types/2'(A).
assumed_store_type(A, B) :-
    'assumed_store_type/2__0'(A, B, _).
'assumed_store_type/2__0'(B, C, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'assumed_store_type/2__0'(B, C, A),
                               assumed_store_type(B, C),
                               [B, C]),
    '$insert_in_store_assumed_store_type/2'(A).
validate_store_type_assumption(A) :-
    'validate_store_type_assumption/1__0'(A, _).
'validate_store_type_assumption/1__0'(A, _) :-
    '$via1_multi_hash_assumed_store_type/2-1'(A, F),
    '$via1_multi_hash_actual_store_types/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, L),
    D=mutable(active),
    E==A,
    member(G, F),
    G=suspension(_, H, _, _, _, _, I, _),
    H=mutable(active),
    I==A,
    !,
    remove_constraint_internal(C, _, J),
    (   J==yes
    ->  '$delete_from_store_actual_store_types/2'(C)
    ;   true
    ),
    remove_constraint_internal(G, _, K),
    (   K==yes
    ->  '$delete_from_store_assumed_store_type/2'(G)
    ;   true
    ),
    store_type(A, multi_store(L)).
'validate_store_type_assumption/1__0'(A, _) :-
    '$via1_multi_hash_store_type/2-1'(A, F),
    '$via1_multi_hash_actual_store_types/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, L),
    D=mutable(active),
    E==A,
    member(G, F),
    G=suspension(_, H, _, _, _, _, I, _),
    H=mutable(active),
    I==A,
    !,
    remove_constraint_internal(C, _, J),
    (   J==yes
    ->  '$delete_from_store_actual_store_types/2'(C)
    ;   true
    ),
    remove_constraint_internal(G, _, K),
    (   K==yes
    ->  '$delete_from_store_store_type/2'(G)
    ;   true
    ),
    store_type(A, multi_store(L)).
'validate_store_type_assumption/1__0'(_, _) :-
    !.
rule_count(A) :-
    'rule_count/1__0'(A, _).
'rule_count/1__0'(B, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'rule_count/1__0'(B, A),
                               rule_count(B),
                               [B]),
    '$insert_in_store_rule_count/1'(A).
inc_rule_count(A) :-
    'inc_rule_count/1__0'(A, _).
'inc_rule_count/1__0'(E, _) :-
    nb_getval('$chr_store_global_ground_chr_translate:rule_count/1', A),
    member(B, A),
    B=suspension(_, C, _, _, _, _, F),
    C=mutable(active),
    !,
    remove_constraint_internal(B, _, D),
    (   D==yes
    ->  '$delete_from_store_rule_count/1'(B)
    ;   true
    ),
    E is F+1,
    rule_count(E).
'inc_rule_count/1__0'(A, _) :-
    !,
    A=1,
    rule_count(A).
get_rule_count(A) :-
    'get_rule_count/1__0'(A, _).
'get_rule_count/1__0'(D, _) :-
    nb_getval('$chr_store_global_ground_chr_translate:rule_count/1', A),
    member(B, A),
    B=suspension(_, C, _, _, _, _, E),
    C=mutable(active),
    !,
    D=E.
'get_rule_count/1__0'(A, _) :-
    !,
    A=0.
passive(A, B) :-
    'passive/2__0'(A, B, _).
'passive/2__0'(A, B, C) :-
    nb_getval('$chr_store_global_ground_chr_translate:allocation_occurrence/2',
              D),
    !,
    allocate_constraint(chr_translate:'passive/2__0'(A, B, C),
                        C,
                        passive(A, B),
                        [A, B]),
    'passive/2__0__0'(D, A, B, C).
'passive/2__0__0'([], A, B, C) :-
    'passive/2__1'(A, B, C).
'passive/2__0__0'([A|U], E, F, O) :-
    (   ( A=suspension(_, B, _, _, _, _, C, D),
          B=mutable(active)
        ),
        '$via1_multi_hash_occurrence/4-1234'(k(C,
                                               D,
                                               E,
                                               F),
                                             G),
        member(H, G),
        H=suspension(_, I, _, _, _, _, J, K, L, M),
        I=mutable(active),
        J==C,
        K==D,
        L==E,
        M==F
    ->  ( remove_constraint_internal(A, _, N),
          (   N==yes
          ->  '$delete_from_store_allocation_occurrence/2'(A)
          ;   true
          )
        ),
        ( activate_constraint(P, _, O, T),
          (   P==yes
          ->  '$insert_in_store_passive/2'(O)
          ;   true
          )
        ),
        ( Q is D+1,
          allocation_occurrence(C, Q)
        ),
        (   O=suspension(_, R, _, S, _, _, _, _),
            R=mutable(active),
            S=mutable(T)
        ->  'chr update_mutable'(inactive, R),
            'passive/2__0__0'(U, E, F, O)
        ;   true
        )
    ;   'passive/2__0__0'(U, E, F, O)
    ).
'passive/2__0'(A, B, C) :-
    allocate_constraint(chr_translate:'passive/2__0'(A, B, C),
                        C,
                        passive(A, B),
                        [A, B]),
    'passive/2__1'(A, B, C).
'passive/2__1'(_, _, A) :-
    activate_constraint(B, _, A, _),
    (   B==yes
    ->  '$insert_in_store_passive/2'(A)
    ;   true
    ).
is_passive(A, B) :-
    'is_passive/2__0'(A, B, _).
'is_passive/2__0'(A, B, _) :-
    '$via1_multi_hash_passive/2-12'(k(A, B), C),
    member(D, C),
    D=suspension(_, E, _, _, _, _, F, G),
    E=mutable(active),
    F==A,
    G==B,
    !.
'is_passive/2__0'(_, _, _) :-
    !,
    fail.
any_passive_head(A) :-
    'any_passive_head/1__0'(A, _).
'any_passive_head/1__0'(A, _) :-
    '$via1_multi_hash_passive/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, _),
    D=mutable(active),
    E==A,
    !.
'any_passive_head/1__0'(_, _) :-
    !,
    fail.
pragma_unique(A, B, C) :-
    'pragma_unique/3__0'(A, B, C, _).
'pragma_unique/3__0'(B, C, D, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'pragma_unique/3__0'(B, C, D, A),
                               pragma_unique(B, C, D),
                               [B, C, D]),
    '$insert_in_store_pragma_unique/3'(A).
get_pragma_unique(A, B, C) :-
    'get_pragma_unique/3__0'(A, B, C, _).
'get_pragma_unique/3__0'(A, B, H, _) :-
    '$via1_multi_hash_pragma_unique/3-12'(k(A, B), C),
    member(D, C),
    D=suspension(_, E, _, _, _, _, F, G, I),
    E=mutable(active),
    F==A,
    G==B,
    !,
    H=I.
'get_pragma_unique/3__0'(_, _, _, _) :-
    !.
occurrence(A, B, C, D) :-
    'occurrence/4__0'(A, B, C, D, _).
'occurrence/4__0'(A, B, C, D, E) :-
    allocate_constraint(chr_translate:'occurrence/4__0'(A, B, C, D, E),
                        E,
                        occurrence(A, B, C, D),
                        [A, B, C, D]),
    (   'chr novel_production'(E, 46),
        !,
        'chr extend_history'(E, 46),
        activate_constraint(F, _, E, I),
        (   F==yes
        ->  '$insert_in_store_occurrence/4'(E)
        ;   true
        ),
        max_occurrence(A, B),
        (   E=suspension(_, G, _, H, _, _, _, _, _, _),
            G=mutable(active),
            H=mutable(I)
        ->  'chr update_mutable'(inactive, G),
            'occurrence/4__1'(A, B, C, D, E)
        ;   true
        )
    ;   'occurrence/4__1'(A, B, C, D, E)
    ).
'occurrence/4__1'(A, B, D, E, F) :-
    '$via1_multi_hash_allocation_occurrence/2-12'(k(A, B), C),
    !,
    'occurrence/4__1__0'(C, A, B, D, E, F).
'occurrence/4__1__0'([], A, B, C, D, E) :-
    'occurrence/4__2'(A, B, C, D, E).
'occurrence/4__1__0'([A|U], D, F, G, M, O) :-
    (   ( A=suspension(_, B, _, _, _, _, C, E),
          B=mutable(active)
        ),
        ( C==D,
          E==F
        ),
        '$via1_multi_hash_rule/2-1'(G, H),
        ( member(I, H),
          I=suspension(_, J, _, _, _, _, K, L),
          J=mutable(active),
          K==G
        ),
        ( 'chr lock'(L),
          'chr lock'(M)
        ),
        ( L=pragma(_, ids(_, _), _, _, _),
          member(M, _)
        ),
        'chr unlock'(L),
        'chr unlock'(M)
    ->  ( remove_constraint_internal(A, _, N),
          (   N==yes
          ->  '$delete_from_store_allocation_occurrence/2'(A)
          ;   true
          )
        ),
        ( activate_constraint(P, _, O, T),
          (   P==yes
          ->  '$insert_in_store_occurrence/4'(O)
          ;   true
          )
        ),
        ( Q is F+1,
          allocation_occurrence(D, Q)
        ),
        (   O=suspension(_, R, _, S, _, _, _, _, _, _),
            R=mutable(active),
            S=mutable(T)
        ->  'chr update_mutable'(inactive, R),
            'occurrence/4__1__0'(U,
                                 D,
                                 F,
                                 G,
                                 M,
                                 O)
        ;   true
        )
    ;   'occurrence/4__1__0'(U, D, F, G, M, O)
    ).
'occurrence/4__1'(A, B, C, D, E) :-
    'occurrence/4__2'(A, B, C, D, E).
'occurrence/4__2'(A, B, D, E, F) :-
    '$via1_multi_hash_allocation_occurrence/2-12'(k(A, B), C),
    !,
    'occurrence/4__2__0'(C, A, B, D, E, F).
'occurrence/4__2__0'([], A, B, C, D, E) :-
    'occurrence/4__3'(A, B, C, D, E).
'occurrence/4__2__0'([A|T], D, F, G, U, N) :-
    (   ( A=suspension(_, B, _, _, _, _, C, E),
          B=mutable(active)
        ),
        ( C==D,
          E==F
        ),
        '$via1_multi_hash_rule/2-1'(G, H),
        ( member(I, H),
          I=suspension(_, J, _, _, _, _, K, L),
          J=mutable(active),
          K==G
        ),
        'chr lock'(L),
        L=pragma(rule(_, _, _, true), _, _, _, _),
        'chr unlock'(L)
    ->  ( remove_constraint_internal(A, _, M),
          (   M==yes
          ->  '$delete_from_store_allocation_occurrence/2'(A)
          ;   true
          )
        ),
        ( activate_constraint(O, _, N, S),
          (   O==yes
          ->  '$insert_in_store_occurrence/4'(N)
          ;   true
          )
        ),
        ( P is F+1,
          allocation_occurrence(D, P)
        ),
        (   N=suspension(_, Q, _, R, _, _, _, _, _, _),
            Q=mutable(active),
            R=mutable(S)
        ->  'chr update_mutable'(inactive, Q),
            'occurrence/4__2__0'(T,
                                 D,
                                 F,
                                 G,
                                 U,
                                 N)
        ;   true
        )
    ;   'occurrence/4__2__0'(T, D, F, G, U, N)
    ).
'occurrence/4__2'(A, B, C, D, E) :-
    'occurrence/4__3'(A, B, C, D, E).
'occurrence/4__3'(A, B, D, E, F) :-
    '$via1_multi_hash_allocation_occurrence/2-12'(k(A, B), C),
    !,
    'occurrence/4__3__0'(C, A, B, D, E, F).
'occurrence/4__3__0'([], A, B, C, D, E) :-
    'occurrence/4__4'(A, B, C, D, E).
'occurrence/4__3__0'([A|U], D, F, G, H, O) :-
    (   ( A=suspension(_, B, _, _, _, _, C, E),
          B=mutable(active)
        ),
        ( C==D,
          E==F
        ),
        '$via1_multi_hash_passive/2-12'(k(G, H), I),
        member(J, I),
        J=suspension(_, K, _, _, _, _, L, M),
        K=mutable(active),
        L==G,
        M==H
    ->  ( remove_constraint_internal(A, _, N),
          (   N==yes
          ->  '$delete_from_store_allocation_occurrence/2'(A)
          ;   true
          )
        ),
        ( activate_constraint(P, _, O, T),
          (   P==yes
          ->  '$insert_in_store_occurrence/4'(O)
          ;   true
          )
        ),
        ( Q is F+1,
          allocation_occurrence(D, Q)
        ),
        (   O=suspension(_, R, _, S, _, _, _, _, _, _),
            R=mutable(active),
            S=mutable(T)
        ->  'chr update_mutable'(inactive, R),
            'occurrence/4__3__0'(U,
                                 D,
                                 F,
                                 G,
                                 H,
                                 O)
        ;   true
        )
    ;   'occurrence/4__3__0'(U, D, F, G, H, O)
    ).
'occurrence/4__3'(A, B, C, D, E) :-
    'occurrence/4__4'(A, B, C, D, E).
'occurrence/4__4'(_, _, _, _, A) :-
    activate_constraint(B, _, A, _),
    (   B==yes
    ->  '$insert_in_store_occurrence/4'(A)
    ;   true
    ).
get_occurrence(A, B, C, D) :-
    'get_occurrence/4__0'(A, B, C, D, _).
'get_occurrence/4__0'(F, A, I, K, _) :-
    '$via1_multi_hash_occurrence/4-2'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, G, H, J),
    D=mutable(active),
    E==F,
    G==A,
    !,
    H=I,
    J=K.
'get_occurrence/4__0'(_, _, _, _, _) :-
    !,
    fail.
max_occurrence(A, B) :-
    'max_occurrence/2__0'(A, B, _).
'max_occurrence/2__0'(A, G, H) :-
    '$via1_multi_hash_max_occurrence/2-1'(A, B),
    (   member(C, B),
        C=suspension(_, D, _, _, _, _, E, F),
        D=mutable(active),
        E==A,
        F>=G,
        !
    ;   !,
        allocate_constraint(chr_translate:'max_occurrence/2__0'(A, G, H),
                            H,
                            max_occurrence(A, G),
                            [A, G]),
        'max_occurrence/2__0__0'(B, A, G, H)
    ).
'max_occurrence/2__0__0'([], A, B, C) :-
    'max_occurrence/2__1'(A, B, C).
'max_occurrence/2__0__0'([A|H], D, E, I) :-
    (   ( A=suspension(_, B, _, _, _, _, C, F),
          B=mutable(active)
        ),
        C==D,
        E>=F
    ->  ( remove_constraint_internal(A, _, G),
          (   G==yes
          ->  '$delete_from_store_max_occurrence/2'(A)
          ;   true
          )
        ),
        'max_occurrence/2__0__0'(H, D, E, I)
    ;   'max_occurrence/2__0__0'(H, D, E, I)
    ).
'max_occurrence/2__0'(A, B, C) :-
    allocate_constraint(chr_translate:'max_occurrence/2__0'(A, B, C),
                        C,
                        max_occurrence(A, B),
                        [A, B]),
    'max_occurrence/2__1'(A, B, C).
'max_occurrence/2__1'(_, _, A) :-
    activate_constraint(B, _, A, _),
    (   B==yes
    ->  '$insert_in_store_max_occurrence/2'(A)
    ;   true
    ).
get_max_occurrence(A, B) :-
    'get_max_occurrence/2__0'(A, B, _).
'get_max_occurrence/2__0'(A, F, _) :-
    '$via1_multi_hash_max_occurrence/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, G),
    D=mutable(active),
    E==A,
    !,
    F=G.
'get_max_occurrence/2__0'(_, A, _) :-
    !,
    A=0.
allocation_occurrence(A, B) :-
    'allocation_occurrence/2__0'(A, B, _).
'allocation_occurrence/2__0'(F, A, _) :-
    ( '$via1_multi_hash_occurrence/4-2'(A, B),
      member(C, B),
      C=suspension(_, D, _, _, _, _, E, G, H, N),
      D=mutable(active),
      E==F,
      G==A
    ),
    (   '$via1_multi_hash_rule/2-1'(H, I),
        member(J, I),
        J=suspension(_, K, _, _, _, _, L, M),
        K=mutable(active),
        L==H,
        'chr lock'(M),
        (   'chr lock'(N),
            M=pragma(_, ids(_, _), _, _, _),
            member(N, _),
            'chr unlock'(M),
            'chr unlock'(N),
            !,
            O is A+1,
            allocation_occurrence(F, O)
        ;   M=pragma(rule(_, _, _, true), _, _, _, _),
            'chr unlock'(M),
            !,
            P is A+1,
            allocation_occurrence(F, P)
        )
    ;   '$via1_multi_hash_passive/2-12'(k(H, N), Q),
        member(R, Q),
        R=suspension(_, S, _, _, _, _, T, U),
        S=mutable(active),
        T==H,
        U==N,
        !,
        V is A+1,
        allocation_occurrence(F, V)
    ).
'allocation_occurrence/2__0'(B, C, A) :-
    insert_constraint_internal(_,
                               _,
                               A,
                               chr_translate:'allocation_occurrence/2__0'(B, C, A),
                               allocation_occurrence(B, C),
                               [B, C]),
    '$insert_in_store_allocation_occurrence/2'(A).
get_allocation_occurrence(A, B) :-
    'get_allocation_occurrence/2__0'(A, B, _).
'get_allocation_occurrence/2__0'(A, F, _) :-
    '$via1_multi_hash_allocation_occurrence/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, G),
    D=mutable(active),
    E==A,
    !,
    F=G.
'get_allocation_occurrence/2__0'(_, _, _) :-
    !,
    fail.
rule(A, B) :-
    'rule/2__0'(A, B, _).
'rule/2__0'(A, B, C) :-
    nb_getval('$chr_store_global_ground_chr_translate:allocation_occurrence/2',
              D),
    !,
    allocate_constraint(chr_translate:'rule/2__0'(A, B, C),
                        C,
                        rule(A, B),
                        [A, B]),
    'rule/2__0__0'(D, A, B, C).
'rule/2__0__0'([], A, B, C) :-
    'rule/2__1'(A, B, C).
'rule/2__0__0'([A|U], C, L, O) :-
    (   ( A=suspension(_, B, _, _, _, _, H, J),
          B=mutable(active)
        ),
        '$via1_multi_hash_occurrence/4-3'(C, D),
        ( member(E, D),
          E=suspension(_, F, _, _, _, _, G, I, K, M),
          F=mutable(active),
          G==H,
          I==J,
          K==C
        ),
        ( 'chr lock'(L),
          'chr lock'(M)
        ),
        ( L=pragma(_, ids(_, _), _, _, _),
          member(M, _)
        ),
        'chr unlock'(L),
        'chr unlock'(M)
    ->  ( remove_constraint_internal(A, _, N),
          (   N==yes
          ->  '$delete_from_store_allocation_occurrence/2'(A)
          ;   true
          )
        ),
        ( activate_constraint(P, _, O, T),
          (   P==yes
          ->  '$insert_in_store_rule/2'(O)
          ;   true
          )
        ),
        ( Q is J+1,
          allocation_occurrence(H, Q)
        ),
        (   O=suspension(_, R, _, S, _, _, _, _),
            R=mutable(active),
            S=mutable(T)
        ->  'chr update_mutable'(inactive, R),
            'rule/2__0__0'(U, C, L, O)
        ;   true
        )
    ;   'rule/2__0__0'(U, C, L, O)
    ).
'rule/2__0'(A, B, C) :-
    allocate_constraint(chr_translate:'rule/2__0'(A, B, C),
                        C,
                        rule(A, B),
                        [A, B]),
    'rule/2__1'(A, B, C).
'rule/2__1'(B, C, D) :-
    nb_getval('$chr_store_global_ground_chr_translate:allocation_occurrence/2',
              A),
    !,
    'rule/2__1__0'(A, B, C, D).
'rule/2__1__0'([], A, B, C) :-
    'rule/2__2'(A, B, C).
'rule/2__1__0'([A|T], C, L, N) :-
    (   ( A=suspension(_, B, _, _, _, _, H, J),
          B=mutable(active)
        ),
        '$via1_multi_hash_occurrence/4-3'(C, D),
        ( member(E, D),
          E=suspension(_, F, _, _, _, _, G, I, K, _),
          F=mutable(active),
          G==H,
          I==J,
          K==C
        ),
        'chr lock'(L),
        L=pragma(rule(_, _, _, true), _, _, _, _),
        'chr unlock'(L)
    ->  ( remove_constraint_internal(A, _, M),
          (   M==yes
          ->  '$delete_from_store_allocation_occurrence/2'(A)
          ;   true
          )
        ),
        ( activate_constraint(O, _, N, S),
          (   O==yes
          ->  '$insert_in_store_rule/2'(N)
          ;   true
          )
        ),
        ( P is J+1,
          allocation_occurrence(H, P)
        ),
        (   N=suspension(_, Q, _, R, _, _, _, _),
            Q=mutable(active),
            R=mutable(S)
        ->  'chr update_mutable'(inactive, Q),
            'rule/2__1__0'(T, C, L, N)
        ;   true
        )
    ;   'rule/2__1__0'(T, C, L, N)
    ).
'rule/2__1'(A, B, C) :-
    'rule/2__2'(A, B, C).
'rule/2__2'(_, _, A) :-
    activate_constraint(B, _, A, _),
    (   B==yes
    ->  '$insert_in_store_rule/2'(A)
    ;   true
    ).
get_rule(A, B) :-
    'get_rule/2__0'(A, B, _).
'get_rule/2__0'(A, F, _) :-
    '$via1_multi_hash_rule/2-1'(A, B),
    member(C, B),
    C=suspension(_, D, _, _, _, _, E, G),
    D=mutable(active),
    E==A,
    !,
    F=G.
'get_rule/2__0'(_, _, _) :-
    !,
    fail.
