%two level L-stratification
%one stable model
%does not pass finite domain check
%returns stable model only if function depth bound is given

formicAcid(fa).
oxalicAcid(oa).

hasAtom(X,f1(X)):- formicAcid(X).
hasAtom(X,f2(X)):- formicAcid(X).
hasAtom(X,f3(X)):- formicAcid(X).
hasAtom(X,f4(X)):- formicAcid(X).
hasAtom(X,f5(X)):- formicAcid(X).
c(f1(X)):- formicAcid(X).
o(f2(X)):- formicAcid(X).
h(f3(X)):- formicAcid(X).
h(f4(X)):- formicAcid(X).
o(f5(X)):- formicAcid(X).
singleBond(f1(X),f2(X)):- formicAcid(X).
singleBond(f2(X),f3(X)):- formicAcid(X).
singleBond(f1(X),f4(X)):- formicAcid(X).
doubleBond(f1(X),f5(X)):- formicAcid(X).

hasAtom(X,g1(X)):- oxalicAcid(X).
hasAtom(X,g2(X)):- oxalicAcid(X).
hasAtom(X,g3(X)):- oxalicAcid(X).
hasAtom(X,g4(X)):- oxalicAcid(X).
hasAtom(X,g5(X)):- oxalicAcid(X).
hasAtom(X,g6(X)):- oxalicAcid(X).
hasAtom(X,g7(X)):- oxalicAcid(X).
hasAtom(X,g8(X)):- oxalicAcid(X).
c(g1(X)):- oxalicAcid(X).
o(g2(X)):- oxalicAcid(X).
h(g3(X)):- oxalicAcid(X).
o(g4(X)):- oxalicAcid(X).
c(g5(X)):- oxalicAcid(X).
o(g6(X)):- oxalicAcid(X).
h(g7(X)):- oxalicAcid(X).
o(g8(X)):- oxalicAcid(X).
singleBond(g1(X),g2(X)):- oxalicAcid(X).
singleBond(g2(X),g3(X)):- oxalicAcid(X).
doubleBond(g1(X),g4(X)):- oxalicAcid(X).
singleBond(g1(X),g5(X)):- oxalicAcid(X).
doubleBond(g5(X),g8(X)):- oxalicAcid(X).
singleBond(g5(X),g6(X)):- oxalicAcid(X).
singleBond(g6(X),g7(X)):- oxalicAcid(X).

rc(u(X,Z1,Z2,Z3,Z4)):- hasAtom(X,Z1), hasAtom(X,Z2), hasAtom(X,Z3), hasAtom(X,Z4), c(Z1), o(Z2), o(Z3), h(Z4), doubleBond(Z1,Z2), singleBond(Z1,Z3), singleBond(Z3,Z4), not gc(Z1), not gc(Z2), not gc(Z3), not gc(Z4).
carboxyl(u(X,Z1,Z2,Z3,Z4)):- hasAtom(X,Z1), hasAtom(X,Z2), hasAtom(X,Z3), hasAtom(X,Z4), c(Z1), o(Z2), o(Z3), h(Z4), doubleBond(Z1,Z2), singleBond(Z1,Z3), singleBond(Z3,Z4), not gc(Z1), not gc(Z2), not gc(Z3), not gc(Z4).
hasAtom(u(X,Z1,Z2,Z3,Z4),Z1):- hasAtom(X,Z1), hasAtom(X,Z2), hasAtom(X,Z3), hasAtom(X,Z4), c(Z1), o(Z2), o(Z3), h(Z4), doubleBond(Z1,Z2), singleBond(Z1,Z3), singleBond(Z3,Z4), not gc(Z1), not gc(Z2), not gc(Z3), not gc(Z4).
hasAtom(u(X,Z1,Z2,Z3,Z4),Z2):- hasAtom(X,Z1), hasAtom(X,Z2), hasAtom(X,Z3), hasAtom(X,Z4), c(Z1), o(Z2), o(Z3), h(Z4), doubleBond(Z1,Z2), singleBond(Z1,Z3), singleBond(Z3,Z4), not gc(Z1), not gc(Z2), not gc(Z3), not gc(Z4).
hasAtom(u(X,Z1,Z2,Z3,Z4),Z3):- hasAtom(X,Z1), hasAtom(X,Z2), hasAtom(X,Z3), hasAtom(X,Z4), c(Z1), o(Z2), o(Z3), h(Z4), doubleBond(Z1,Z2), singleBond(Z1,Z3), singleBond(Z3,Z4), not gc(Z1), not gc(Z2), not gc(Z3), not gc(Z4).
hasAtom(u(X,Z1,Z2,Z3,Z4),Z4):- hasAtom(X,Z1), hasAtom(X,Z2), hasAtom(X,Z3), hasAtom(X,Z4), c(Z1), o(Z2), o(Z3), h(Z4), doubleBond(Z1,Z2), singleBond(Z1,Z3), singleBond(Z3,Z4), not gc(Z1), not gc(Z2), not gc(Z3), not gc(Z4).
hasGroup(X,u(X,Z1,Z2,Z3,Z4)):- hasAtom(X,Z1), hasAtom(X,Z2), hasAtom(X,Z3), hasAtom(X,Z4), c(Z1), o(Z2), o(Z3), h(Z4), doubleBond(Z1,Z2), singleBond(Z1,Z3), singleBond(Z3,Z4), not gc(Z1), not gc(Z2), not gc(Z3), not gc(Z4).

%carboxylicAcid(X):- hasGroup(X,Y), carboxyl(Y).
%atLeast2Carboxyls(X):- hasGroup(X,Y1), hasGroup(X,Y2), carboxyl(Y1), carboxyl(Y2), Y1!=Y2.
%monoCarboxylicAcid(X):- carboxylicAcid(X), not atLeast2Carboxyls(X).

%hasAtom(X,h1(X)):- carboxyl(X), not rc(X).
%hasAtom(X,h2(X)):- carboxyl(X), not rc(X).
%hasAtom(X,h3(X)):- carboxyl(X), not rc(X).
%hasAtom(X,h4(X)):- carboxyl(X), not rc(X).
%c(h1(X)):- carboxyl(X), not rc(X).
%o(h2(X)):- carboxyl(X), not rc(X).
%o(h3(X)):- carboxyl(X), not rc(X).
%h(h4(X)):- carboxyl(X), not rc(X).
%doubleBond(h1(X),h2(X)):- carboxyl(X), not rc(X).
%singleBond(h1(X),h3(X)):- carboxyl(X), not rc(X).
%singleBond(h3(X),h4(X)):- carboxyl(X), not rc(X).
%gc(h1(X)):- carboxyl(X), not rc(X).
%gc(h2(X)):- carboxyl(X), not rc(X).
%gc(h3(X)):- carboxyl(X), not rc(X).
%gc(h4(X)):- carboxyl(X), not rc(X).
