:- module( _, [add/2], [assertions , regtypes , basicmodes , nativeprops] ).

add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))]]],[E,F]) :-
        B>=D,
        D=\=0,
        G is B rem D,
        G\=0,
        H is B+B,
        D=\=0,
        I is H rem D,
        I\=0,
        J is H+B,
        execute_notrace_1(A,B,C,D,J,F,_1,_2,_3,_4,E,_5) .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))]]],[ref(loc(3)),[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))],[num(int(E)),num(int(F))]]]) :-
        B>=D,
        D=\=0,
        G is B rem D,
        G\=0,
        F is B+B,
        D=\=0,
        0 is F rem D,
        B=\=0,
        H is F//B,
        I is H*A,
        D=\=0,
        J is F//D,
        K is J*C,
        E is I+K .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(0))],[num(int(B)),num(int(C))]]],[refE(loc(4)),[[num(int(A)),num(int(0))],[num(int(B)),num(int(C))],[num(int(0)),num(int(0))],[]]]) :-
        0>=C,
        C=\=0,
        D is 0 rem C,
        D\=0,
        C=\=0,
        0 is 0 rem C .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))]]],[ref(loc(3)),[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))],[num(int(E)),num(int(B))]]]) :-
        B>=D,
        D=\=0,
        0 is B rem D,
        B=\=0,
        F is B//B,
        G is F*A,
        D=\=0,
        H is B//D,
        I is H*C,
        E is G+I .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(0))],[num(int(B)),num(int(C))]]],[refE(loc(4)),[[num(int(A)),num(int(0))],[num(int(B)),num(int(C))],[num(int(0)),num(int(0))],[]]]) :-
        0>=C,
        C=\=0,
        0 is 0 rem C .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(B))],[num(int(C)),num(int(0))]]],[refE(loc(3)),[[num(int(A)),num(int(B))],[num(int(C)),num(int(0))],[]]]) :-
        B>=0 .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))]]],[E,F]) :-
        B<D,
        B=\=0,
        G is D rem B,
        G\=0,
        H is D+D,
        B=\=0,
        I is H rem B,
        I\=0,
        J is H+D,
        execute_notrace_2(A,B,C,D,D,B,J,F,_1,_2,_3,_4,E,_5) .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))]]],[ref(loc(3)),[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))],[num(int(E)),num(int(F))]]]) :-
        B<D,
        B=\=0,
        G is D rem B,
        G\=0,
        F is D+D,
        B=\=0,
        0 is F rem B,
        B=\=0,
        H is F//B,
        I is H*A,
        D=\=0,
        J is F//D,
        K is J*C,
        E is I+K .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(B))],[num(int(C)),num(int(0))]]],[refE(loc(4)),[[num(int(A)),num(int(B))],[num(int(C)),num(int(0))],[num(int(0)),num(int(0))],[]]]) :-
        B<0,
        B=\=0,
        D is 0 rem B,
        D\=0,
        B=\=0,
        0 is 0 rem B,
        B=\=0,
        E is 0//B,
        _1 is E*A .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))]]],[ref(loc(3)),[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))],[num(int(E)),num(int(D))]]]) :-
        B<D,
        B=\=0,
        0 is D rem B,
        B=\=0,
        F is D//B,
        G is F*A,
        D=\=0,
        H is D//D,
        I is H*C,
        E is G+I .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(B))],[num(int(C)),num(int(0))]]],[refE(loc(4)),[[num(int(A)),num(int(B))],[num(int(C)),num(int(0))],[num(int(0)),num(int(0))],[]]]) :-
        B<0,
        B=\=0,
        0 is 0 rem B,
        B=\=0,
        D is 0//B,
        _1 is D*A .
add([[ref(loc(1)),ref(loc(2))],[[num(int(A)),num(int(0))],[num(int(B)),num(int(C))]]],[refE(loc(3)),[[num(int(A)),num(int(0))],[num(int(B)),num(int(C))],[]]]) :-
        0<C .
add([[ref(loc(1)),null],[[num(int(A)),num(int(B))]]],[refE(loc(2)),[[num(int(A)),num(int(B))],[]]]).
add([[null,ref(loc(1))],[[num(int(A)),num(int(B))]]],[refE(loc(2)),[[num(int(A)),num(int(B))],[]]]).
add([[null,null],[]],[refE(loc(1)),[[]]]).

execute_notrace_1(A,B,C,D,E,F,G,H,I,J,K,L) :-
        D=\=0,
        M is E rem D,
        M\=0,
        N is E+B,
        execute_notrace_1(A,B,C,D,N,F,G,H,I,J,K,L) .
execute_notrace_1(A,B,C,D,E,[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))],[num(int(F)),num(int(E))]],_1,_2,_3,_4,ref(loc(3)),[]) :-
        D=\=0,
        0 is E rem D,
        B=\=0,
        G is E//B,
        H is G*A,
        D=\=0,
        I is E//D,
        J is I*C,
        F is H+J .
execute_notrace_1(A,0,B,C,D,[[num(int(A)),num(int(0))],[num(int(B)),num(int(C))],[num(int(0)),num(int(0))],[]],_1,_2,_3,_4,refE(loc(4)),[]) :-
        C=\=0,
        0 is D rem C .
execute_notrace_1(A,B,C,0,_1,[[num(int(A)),num(int(B))],[num(int(C)),num(int(0))],[]],_2,_3,_4,_5,refE(loc(3)),[]).

execute_notrace_2(A,B,C,D,E,F,G,H,I,J,K,L,M,N) :-
        F=\=0,
        O is G rem F,
        O\=0,
        P is G+E,
        execute_notrace_2(A,B,C,D,E,F,P,H,I,J,K,L,M,N) .
execute_notrace_2(A,B,C,D,_1,E,F,[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))],[num(int(G)),num(int(F))]],_2,_3,_4,_5,ref(loc(3)),[]) :-
        E=\=0,
        0 is F rem E,
        B=\=0,
        H is F//B,
        I is H*A,
        D=\=0,
        J is F//D,
        K is J*C,
        G is I+K .
execute_notrace_2(A,B,C,0,_1,D,E,[[num(int(A)),num(int(B))],[num(int(C)),num(int(0))],[num(int(0)),num(int(0))],[]],_2,_3,_4,_5,refE(loc(4)),[]) :-
        D=\=0,
        0 is E rem D,
        B=\=0,
        F is E//B,
        _6 is F*A .
execute_notrace_2(A,0,B,C,_1,D,E,[[num(int(A)),num(int(0))],[num(int(B)),num(int(C))],[num(int(0)),num(int(0))],[]],_2,_3,_4,_5,refE(loc(4)),[]) :-
        D=\=0,
        0 is E rem D .
execute_notrace_2(A,B,C,D,_1,0,_2,[[num(int(A)),num(int(B))],[num(int(C)),num(int(D))],[]],_3,_4,_5,_6,refE(loc(3)),[]).


