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


