/* 
maxrec: 2
max_depth: 4
maxnondeterm: 10
maxpropleft: 3
maxlevel: 0
maxfinite: 7
quickpe: 0
tracing: unset
delayoutput: unset
handle_freeze: set
cyclic: set
comments: set
tracegoalstack: unset
arithopt: set
fold_instance: set
preserve_loops: unset
unfold_cut: set
unfold_cut2: unset
print_settings: set
if2cut: unset
rename_VAR: unset
indexargs: set
*/
parse(o(A,B,C)) :-
        parseo1(A, B, C).

% parseo1(A,B,C):-parse(o(A,B,C))
parseo1(_, _, _) :-
        hc_in:gap(B, C),
        hc_in:headed_rule(B, _, _, _, A),
        hc_in:headed_rule_i(A, B, _, _, _),
        hc_in:gap_i(C, B),
        format(user_error, [87,97,114,110,105,110,103,58,32,104,101,97,100,45,99,111,114,110,101,114,32,112,97,114,115,101,114,32,117,110,115,111,117,110,100,58,32,126,119,32,97,115,32,104,101,97,100,32,111,102,32,126,119,126,110], [B/C,A]), !,
        fail.
parseo1(K1, M1, _) :-
        length(M1, L1),
        C is L1+1,
        result_cat(K1, D),
        result_tree(K1, E),
        count_edges:reset_program_space,
        (   C=1,
            hc_in:gap(D, J1),
            E=tree(J1,_,[]),
            hc_in:gap_i(J1, D)
        ;   1\==C,
            functor(D, G1, H1),
            functor(T, G1, H1),
            T=..[G1|I1],
            R=..[G1,1,S|I1],
            (   E1=..[G1,1,F1,H1],
                (   table_goal_l:call(table_goal_l:E1),
                    C=<F1 ->
                    true
                ;   F1=C,
                    assertz(table_goal_l:E1),
                    fail
                ) ->
                true
            ;   gen_left1(Y, 1, C),
                hc_in:head_corner_table_lex(T, 1, S, D1, Y, Z),
                lex:lex(Y, Z, D1, X),
                Z=<C,
                head_corner1(D1, Y, Z, T, S, C, W),
                (   copy_term(R, C1),
                    table_item:clause(C1, _, A1),
                    table_item:clause(B1, _, A1),
                    terms:subsumes_chk(B1, R) ->
                    true
                ;   table_item:assertz(R, A1)
                ),
                A1='$ref'(U,V),
                (   table_item:'MEMO_HIS'(U, V, lex(X,Y,Z), W) ->
                    true
                ;   table_item:assertz(table_item:'MEMO_HIS'(U,V,lex(X,Y,Z),W))
                ),
                fail
            ;   true
            ),
            T=D,
            S=C,
            table_item:clause(table_item:R, _, P),
            (   C=1,
                P=gap(Q),
                E=tree(Q,_,[]),
                hc_in:gap_i(Q, D)
            ;   P='$ref'(A,B),
                (   table_item:reconstructed(A, B) ->
                    true
                ;   table_item:assertz(table_item:reconstructed(A,B)),
                    (   table_item:'MEMO_HIS'(A, B, O, I),
                        O=lex(N,K,L),
                        lists:member(M, N),
                        lex_in:total_lex(M, J, _, _),
                        head_corner_2nd1(I, J, K, L, M, E, H, F, G),
                        table_item:assertz(table_item:reconstructed(A,B,F,G,H,E)),
                        fail
                    ;   true
                    )
                ),
                table_item:reconstructed(A, B, 1, C, D, E)
            )
        ).

% gen_left1(A,1,B):-gen_left(A,1,B)
gen_left1(A, A, _).
gen_left1(A, D, C) :-
        B is D+1,
        B<C,
        gen_left1(A, B, C).

% head_corner1(A,B,C,D,E,F,G):-head_corner(A,B,C,D,1,E,1,F,G)
head_corner1(A, 1, B, A, B, _, []).
head_corner1(N, L, I, D, E, F, [rule(O,M,J)|G]) :-
        hc_in:headed_rule(N, A, K, H, O),
        hc_in:head_corner_table(D, 1, E, A, B, C),
        parse_left_ds1(K, B, L, F, M),
        parse_right_ds1(H, I, C, F, J),
        head_corner1(A, B, C, D, E, F, G).

% parse_left_ds1(A,B,C,D,E):-parse_left_ds(A,B,C,1,D,E)
parse_left_ds1([], A, A, _, []).
parse_left_ds1([F|A], B, C, D, [gap(G)|E]) :-
        hc_in:gap(F, G),
        parse_left_ds1(A, B, C, D, E).
parse_left_ds1([I|A], B, T, D, [F|E]) :-
        1\==T,
        functor(I, W, X),
        functor(H, W, X),
        H=..[W|Y],
        G=..[W,C,T|Y],
        (   U=..[W,T,V,X],
            (   table_goal_r:call(table_goal_r:U),
                V=<1 ->
                true
            ;   V=1,
                assertz(table_goal_r:U),
                fail
            ) ->
            true
        ;   gen_left1(N, 1, T),
            hc_in:head_corner_table_lex(H, C, T, S, N, O),
            lex:lex(N, O, S, M),
            O=<T,
            head_corner2(S, N, O, H, C, T, L),
            (   copy_term(G, R),
                table_item:clause(R, _, P),
                table_item:clause(Q, _, P),
                terms:subsumes_chk(Q, G) ->
                true
            ;   table_item:assertz(G, P)
            ),
            P='$ref'(J,K),
            (   table_item:'MEMO_HIS'(J, K, lex(M,N,O), L) ->
                true
            ;   table_item:assertz(table_item:'MEMO_HIS'(J,K,lex(M,N,O),L))
            ),
            fail
        ;   true
        ),
        H=I,
        table_item:clause(table_item:G, _, F),
        1=<C,
        parse_left_ds1(A, B, C, D, E).

% head_corner2(A,B,C,D,E,F,G):-head_corner(A,B,C,D,E,F,1,F,G)
head_corner2(A, B, C, A, B, C, []).
head_corner2(N, L, I, D, E, F, [rule(O,M,J)|G]) :-
        hc_in:headed_rule(N, A, K, H, O),
        hc_in:head_corner_table(D, E, F, A, B, C),
        parse_left_ds1(K, B, L, F, M),
        parse_right_ds1(H, I, C, F, J),
        head_corner2(A, B, C, D, E, F, G).

% parse_right_ds1(A,B,C,D,E):-parse_right_ds(A,B,C,1,D,E)
parse_right_ds1([], A, A, _, []).
parse_right_ds1([F|A], G, C, D, [H|E]) :-
        parsel1(F, G, D, B, H),
        parse_right_ds1(A, B, C, D, E).

% parsel1(A,B,C,D,E):-parse(l,A,B,D,B,C,E)
parsel1(A, C, _, C, gap(B)) :-
        hc_in:gap(A, B).
parsel1(F, R, B, E, C) :-
        R\==B,
        functor(F, U, V),
        functor(G, U, V),
        G=..[U|W],
        D=..[U,R,A|W],
        (   S=..[U,R,T,V],
            (   table_goal_l:call(table_goal_l:S),
                B=<T ->
                true
            ;   T=B,
                assertz(table_goal_l:S),
                fail
            ) ->
            true
        ;   gen_left2(R, B, L),
            hc_in:head_corner_table_lex(G, R, A, Q, L, M),
            lex:lex(L, M, Q, K),
            M=<B,
            head_corner1(Q, L, M, G, R, A, B, J),
            (   copy_term(D, P),
                table_item:clause(P, _, N),
                table_item:clause(O, _, N),
                terms:subsumes_chk(O, D) ->
                true
            ;   table_item:assertz(D, N)
            ),
            N='$ref'(H,I),
            (   table_item:'MEMO_HIS'(H, I, lex(K,L,M), J) ->
                true
            ;   table_item:assertz(table_item:'MEMO_HIS'(H,I,lex(K,L,M),J))
            ),
            fail
        ;   true
        ),
        F=G,
        E=A,
        table_item:clause(table_item:D, _, C),
        A=<B.

% gen_left2(A,B,C):-gen_left(C,A,B)
gen_left2(A, _, A).
gen_left2(D, B, C) :-
        A is D+1,
        A<B,
        gen_left2(A, B, C).

% head_corner1(A,B,C,D,E,F,G,H):-head_corner(A,B,C,D,E,F,E,G,H)
head_corner1(A, B, C, A, B, C, _, []).
head_corner1(O, M, J, D, E, F, G, [rule(P,N,K)|H]) :-
        hc_in:headed_rule(O, A, L, I, P),
        hc_in:head_corner_table(D, E, F, A, B, C),
        parse_left_ds1(L, B, M, E, G, N),
        parse_right_ds1(I, J, C, E, G, K),
        head_corner1(A, B, C, D, E, F, G, H).

% parse_left_ds1(A,B,C,D,E,F):-parse_left_ds(A,B,C,D,E,F)
parse_left_ds1([], A, A, _, _, []).
parse_left_ds1([G|A], B, C, D, E, [gap(H)|F]) :-
        hc_in:gap(G, H),
        parse_left_ds1(A, B, C, D, E, F).
parse_left_ds1([J|A], B, U, D, E, [G|F]) :-
        D\==U,
        functor(J, X, Y),
        functor(I, X, Y),
        I=..[X|Z],
        H=..[X,C,U|Z],
        (   V=..[X,U,W,Y],
            (   table_goal_r:call(table_goal_r:V),
                W=<D ->
                true
            ;   D=W,
                assertz(table_goal_r:V),
                fail
            ) ->
            true
        ;   gen_left2(D, U, O),
            hc_in:head_corner_table_lex(I, C, U, T, O, P),
            lex:lex(O, P, T, N),
            P=<U,
            head_corner2(T, O, P, I, C, U, D, M),
            (   copy_term(H, S),
                table_item:clause(S, _, Q),
                table_item:clause(R, _, Q),
                terms:subsumes_chk(R, H) ->
                true
            ;   table_item:assertz(H, Q)
            ),
            Q='$ref'(K,L),
            (   table_item:'MEMO_HIS'(K, L, lex(N,O,P), M) ->
                true
            ;   table_item:assertz(table_item:'MEMO_HIS'(K,L,lex(N,O,P),M))
            ),
            fail
        ;   true
        ),
        I=J,
        table_item:clause(table_item:H, _, G),
        D=<C,
        parse_left_ds1(A, B, C, D, E, F).

% head_corner2(A,B,C,D,E,F,G,H):-head_corner(A,B,C,D,E,F,G,F,H)
head_corner2(A, B, C, A, B, C, _, []).
head_corner2(O, M, J, D, E, F, G, [rule(P,N,K)|H]) :-
        hc_in:headed_rule(O, A, L, I, P),
        hc_in:head_corner_table(D, E, F, A, B, C),
        parse_left_ds1(L, B, M, G, F, N),
        parse_right_ds1(I, J, C, G, F, K),
        head_corner2(A, B, C, D, E, F, G, H).

% parse_right_ds1(A,B,C,D,E,F):-parse_right_ds(A,B,C,D,E,F)
parse_right_ds1([], A, A, _, _, []).
parse_right_ds1([G|A], H, C, D, E, [I|F]) :-
        parsel1(G, H, E, B, I),
        parse_right_ds1(A, B, C, D, E, F).

% head_corner_2nd1(A,B,C,D,E,F,G,H,I):-head_corner_2nd(A,B,G,C,D,H,I,tree(E,J,[]),F)
head_corner_2nd1([], A, B, C, D, tree(D,_,[]), A, B, C).
head_corner_2nd1([rule(E,O,K)|A], S, Q, M, R, G, H, I, J) :-
        hc_in:headed_rule_i(E, S, B, P, L),
        parse_lds_2nd2(O, P, C, Q, R, _, N, F),
        parse_rds_2nd1(K, L, M, N, D),
        head_corner_2nd1(A, B, C, D, E, F, G, H, I, J).

% parse_lds_2nd2(A,B,C,D,E,F,G,H):-parse_lds_2nd(A,B,C,D,[tree(E,F,[])|G],H)
parse_lds_2nd2([], [], A, A, B, C, D, [tree(B,C,[])|D]).
parse_lds_2nd2([gap(E)|A], [J|B], C, D, H, I, G, F) :-
        hc_in:gap_i(E, J),
        parse_lds_2nd2(A, B, C, D, E, _, [tree(H,I,[])|G], F).
parse_lds_2nd2(['$ref'(J,K)|A], [M|B], C, L, H, I, F, G) :-
        (   table_item:reconstructed(J, K) ->
            true
        ;   table_item:assertz(table_item:reconstructed(J,K)),
            (   table_item:'MEMO_HIS'(J, K, W, Q),
                W=lex(V,S,T),
                lists:member(U, V),
                lex_in:total_lex(U, R, _, _),
                head_corner_2nd1(Q, R, S, T, U, E, P, N, O),
                table_item:assertz(table_item:reconstructed(J,K,N,O,P,E)),
                fail
            ;   true
            )
        ),
        table_item:reconstructed(J, K, D, L, M, E),
        parse_lds_2nd3(A, B, C, D, E, tree(H,I,[]), F, G).

% parse_lds_2nd3(A,B,C,D,E,tree(F,G,[]),H,I):-parse_lds_2nd(A,B,C,D,[E,tree(F,G,[])|H],I)
parse_lds_2nd3([], [], A, A, B, C, D, [B,C|D]).
parse_lds_2nd3([gap(I)|A], [J|B], C, D, E, G, H, F) :-
        hc_in:gap_i(I, J),
        parse_lds_2nd3(A, B, C, D, tree(I,_,[]), E, [G|H], F).
parse_lds_2nd3(['$ref'(J,K)|A], [M|B], C, L, F, H, I, G) :-
        (   table_item:reconstructed(J, K) ->
            true
        ;   table_item:assertz(table_item:reconstructed(J,K)),
            (   table_item:'MEMO_HIS'(J, K, W, Q),
                W=lex(V,S,T),
                lists:member(U, V),
                lex_in:total_lex(U, R, _, _),
                head_corner_2nd1(Q, R, S, T, U, E, P, N, O),
                table_item:assertz(table_item:reconstructed(J,K,N,O,P,E)),
                fail
            ;   true
            )
        ),
        table_item:reconstructed(J, K, D, L, M, E),
        parse_lds_2nd3(A, B, C, D, E, F, [H|I], G).

% parse_rds_2nd1(A,B,C,D,E):-parse_rds_2nd(A,B,C,E,D)
parse_rds_2nd1([], [], A, [], A).
parse_rds_2nd1([gap(F)|A], [G|B], C, [tree(F,_,[])|D], E) :-
        hc_in:gap_i(F, G),
        parse_rds_2nd1(A, B, C, D, E).
parse_rds_2nd1(['$ref'(F,G)|A], [I|B], H, [J|D], E) :-
        (   table_item:reconstructed(F, G) ->
            true
        ;   table_item:assertz(table_item:reconstructed(F,G)),
            (   table_item:'MEMO_HIS'(F, G, T, N),
                T=lex(S,P,Q),
                lists:member(R, S),
                lex_in:total_lex(R, O, _, _),
                head_corner_2nd1(N, O, P, Q, R, J, M, K, L),
                table_item:assertz(table_item:reconstructed(F,G,K,L,M,J)),
                fail
            ;   true
            )
        ),
        table_item:reconstructed(F, G, H, C, I, J),
        parse_rds_2nd1(A, B, C, D, E).

% head_corner_2nd1(A,B,C,D,E,F,G,H,I,J):-head_corner_2nd(A,B,H,C,D,I,J,tree(E,K,F),G)
head_corner_2nd1([], A, B, C, D, E, tree(D,_,E), A, B, C).
head_corner_2nd1([rule(E,O,K)|A], T, Q, M, R, S, G, H, I, J) :-
        hc_in:headed_rule_i(E, T, B, P, L),
        parse_lds_2nd3(O, P, C, Q, R, _, S, N, F),
        parse_rds_2nd1(K, L, M, N, D),
        head_corner_2nd1(A, B, C, D, E, F, G, H, I, J).

% parse_lds_2nd3(A,B,C,D,E,F,G,H,I):-parse_lds_2nd(A,B,C,D,[tree(E,F,G)|H],I)
parse_lds_2nd3([], [], A, A, B, C, D, E, [tree(B,C,D)|E]).
parse_lds_2nd3([gap(E)|A], [K|B], C, D, H, I, J, G, F) :-
        hc_in:gap_i(E, K),
        parse_lds_2nd3(A, B, C, D, E, _, [], [tree(H,I,J)|G], F).
parse_lds_2nd3(['$ref'(K,L)|A], [N|B], C, M, H, I, J, F, G) :-
        (   table_item:reconstructed(K, L) ->
            true
        ;   table_item:assertz(table_item:reconstructed(K,L)),
            (   table_item:'MEMO_HIS'(K, L, X, R),
                X=lex(W,T,U),
                lists:member(V, W),
                lex_in:total_lex(V, S, _, _),
                head_corner_2nd1(R, S, T, U, V, [], E, Q, O, P),
                table_item:assertz(table_item:reconstructed(K,L,O,P,Q,E)),
                fail
            ;   true
            )
        ),
        table_item:reconstructed(K, L, D, M, N, E),
        parse_lds_2nd5(A, B, C, D, E, tree(H,I,J), F, G).

% parse_lds_2nd5(A,B,C,D,E,tree(F,G,H),I,J):-parse_lds_2nd(A,B,C,D,[E,tree(F,G,H)|I],J)
parse_lds_2nd5([], [], A, A, B, C, D, [B,C|D]).
parse_lds_2nd5([gap(I)|A], [J|B], C, D, E, G, H, F) :-
        hc_in:gap_i(I, J),
        parse_lds_2nd5(A, B, C, D, tree(I,_,[]), E, [G|H], F).
parse_lds_2nd5(['$ref'(J,K)|A], [M|B], C, L, F, H, I, G) :-
        (   table_item:reconstructed(J, K) ->
            true
        ;   table_item:assertz(table_item:reconstructed(J,K)),
            (   table_item:'MEMO_HIS'(J, K, W, Q),
                W=lex(V,S,T),
                lists:member(U, V),
                lex_in:total_lex(U, R, _, _),
                head_corner_2nd1(Q, R, S, T, U, [], E, P, N, O),
                table_item:assertz(table_item:reconstructed(J,K,N,O,P,E)),
                fail
            ;   true
            )
        ),
        table_item:reconstructed(J, K, D, L, M, E),
        parse_lds_2nd5(A, B, C, D, E, F, [H|I], G).
dump_grammar :-
        dump_grammar1.

% dump_grammar1:-dump_grammar
dump_grammar1 :-
        hc_compile:dump_grammar.
count :-
        count1.

% count1:-count
count1 :-
        (   flags:flag(debug, 1) ->
            count_edges:report_program_space,
            count_edges:count_edges((table_goal_l:current_predicate(_,H),table_goal_l:H;table_goal_r:current_predicate(_,H),table_goal_r:H), G),
            format(user_error, [126,119,32,103,111,97,108,115,126,110], [G]),
            count_edges:count_edges((table_item:current_predicate(_,D),functor(D,E,F),E/F\=='MEMO_HIS'/4,E/F\==reconstructed/2,E/F\==reconstructed/6,table_item:D), C),
            format(user_error, [126,119,32,105,116,101,109,115,126,110], [C]),
            count_edges:report_count_edges(table_item:'MEMO_HIS'(_,_,_,_)),
            count_edges:report_count_edges(table_item:reconstructed(_,_)),
            count_edges:report_count_edges(table_item:reconstructed(_,_,_,_,_,_))
        ;   flags:flag(debug, 2) ->
            count_edges:report_program_space,
            (   format(user_error, [103,111,97,108,115,58,32,126,110], []),
                table_goal_l:current_predicate(_, table_goal_l:B),
                count_edges:report_count_edges(table_goal_l:B),
                table_goal_r:current_predicate(_, table_goal_r:B),
                count_edges:report_count_edges(table_goal_r:B),
                fail
            ;   format(user_error, [126,110,105,116,101,109,115,58,32,126,110], []),
                table_item:current_predicate(_, table_item:A),
                count_edges:report_count_edges(table_item:A),
                fail
            ;   true
            )
        ;   true
        ).
count(A) :-
        count1(A).

% count1(A):-count(A)
count1(A) :-
        count_edges:program_space(A).
clean :-
        clean1.

% clean1:-clean
clean1 :-
        table_goal_l:current_predicate(_, table_goal_l:C),
        functor(C, A, B),
        table_goal_l:abolish(table_goal_l:A/B),
        fail.
clean1 :-
        table_goal_r:current_predicate(_, table_goal_r:C),
        functor(C, A, B),
        table_goal_r:abolish(table_goal_r:A/B),
        fail.
clean1 :-
        table_item:current_predicate(_, table_item:C),
        functor(C, A, B),
        table_item:abolish(table_item:A/B),
        fail.
clean1.
compile_grammar(A) :-
        compile_grammar1(A).

% compile_grammar1(A):-compile_grammar(A)
compile_grammar1(_) :-
        hc_compile:compile_grammar.
