bond(X,Y) :- single(X,Y).
bond(X,Y) :- double(X,Y).
bond(X,Y) :- triple(X,Y).

% molecules that contain barium
bariumMolEntity(X) :- hasAtom(X,Y), ba(Y).

% molecules that contain beryllium
berylliumMolEntity(X) :- hasAtom(X,Y), be(Y).

% molecules that contain calcium
calciumMolEntity(X) :- hasAtom(X,Y), ca(Y).

% molecules that contain magnesium
magnesiumMolEntity(X) :- hasAtom(X,Y), mg(Y).

% molecules that contain radium
radiumMolEntity(X) :- hasAtom(X,Y), ra(Y).

% molecules that contain strontium
strontiumMolEntity(X) :- hasAtom(X,Y), sr(Y).

% molecules that contain halogens
alkalineEarthMetalMolEntity(X) :- bariumMolEntity(X).
alkalineEarthMetalMolEntity(X) :- berylliumMolEntity(X).
alkalineEarthMetalMolEntity(X) :- calciumMolEntity(X).
alkalineEarthMetalMolEntity(X) :- magnesiumMolEntity(X).
alkalineEarthMetalMolEntity(X) :- radiumMolEntity(X).
alkalineEarthMetalMolEntity(X) :- strontiumMolEntity(X).

% molecules that contain astatine
astatineMolEntity(X) :- hasAtom(X,Y), at(Y).

% molecules that contain bromine
bromineMolEntity(X) :- hasAtom(X,Y), br(Y).

% molecules that contain chlorine
chlorineMolEntity(X) :- hasAtom(X,Y), cl(Y).

% molecules that contain fluorine
fluorineMolEntity(X) :- hasAtom(X,Y), f(Y).

% molecules that contain iodine
iodineMolEntity(X) :- hasAtom(X,Y), i(Y).

% molecules that contain halogens
halogenMolEntity(X) :- bromineMolEntity(X).
halogenMolEntity(X) :- chlorineMolEntity(X).
halogenMolEntity(X) :- fluorineMolEntity(X).
halogenMolEntity(X) :- astatineMolEntity(X).
halogenMolEntity(X) :- iodineMolEntity(X).


% molecules that contain polonium
poloniumMolEntity(X) :- hasAtom(X,Y), po(Y).

% molecules that contain selenium
seleniumMolEntity(X) :- hasAtom(X,Y), se(Y).

% molecules that contain sulfur
sulfurMolEntity(X) :- hasAtom(X,Y), s(Y).

% molecules that contain tellurium
telluriumMolEntity(X) :- hasAtom(X,Y), te(Y).

% molecules that are chalcogens
chalcogenMolEntity(X) :- oxygenMolEntity(X).
chalcogenMolEntity(X) :- poloniumMolEntity(X).
chalcogenMolEntity(X) :- seleniumMolEntity(X).
chalcogenMolEntity(X) :- sulfurMolEntity(X).
chalcogenMolEntity(X) :- telluriumMolEntity(X).

% molecules that contain antimony
antimonyMolEntity(X) :- hasAtom(X,Y), sb(Y).

% molecules that contain arsenic
arsenicMolEntity(X) :- hasAtom(X,Y), as(Y).

% molecules that contain bismuth
bismuthMolEntity(X) :- hasAtom(X,Y), bi(Y).

% molecules that contain nitrogen
nitrogenMolEntity(X) :- hasAtom(X,Y), n(Y).

% molecules that are pnictogens
pnictogenMolEntity(X) :- antimonyMolEntity(X).
pnictogenMolEntity(X) :- arsenicMolEntity(X).
pnictogenMolEntity(X) :- bismuthMolEntity(X).
pnictogenMolEntity(X) :- nitrogenMolEntity(X).
pnictogenMolEntity(X) :- phosphorusMolEntity(X).

% molecules that contain chromium
chromiumMolEntity(X) :- hasAtom(X,Y), cr(Y).

% molecules that contain molybdenum
molybdenumMolEntity(X) :- hasAtom(X,Y), mo(Y).

% molecules that contain seaborgium
seaborgiumMolEntity(X) :- hasAtom(X,Y), sg(Y).

% molecules that contain tungsten
tungstenMolEntity(X) :- hasAtom(X,Y), w(Y).

% molecules that belong to the chromium group
chromiumGroupMolEntity(X) :- chromiumMolEntity(X).
chromiumGroupMolEntity(X) :- molybdenumMolEntity(X).
chromiumGroupMolEntity(X) :- seaborgiumMolEntity(X).
chromiumGroupMolEntity(X) :- tungstenMolEntity(X).

%noble gas atoms
noble(X) :- ar(X).
noble(X) :- he(X).
noble(X) :- kr(X).
noble(X) :- ne(X).
noble(X) :- rn(X).
noble(X) :- xe(X).

% molecules that contain noble gas atoms
nobleGasMolEntity(X) :- hasAtom(X,Y), noble(Y).

% molecules that contain carbon
carbonMolEntity(X) :- hasAtom(X,Y), c(Y).

% molecules that contain oxygen
oxygenMolEntity(X) :- hasAtom(X,Y), o(Y).

% molecules that contain hydrogen
hydrogenMolEntity(X) :- hasAtom(X,Y), h(Y).

% molecules that contain phosphorus
phosphorusMolEntity(X) :- hasAtom(X,Y), p(Y).

% molecules that do not contain carbon
inorganic(X) :- molecule(X), not carbonMolEntity(X).

% molecules that contain carbon, hydrogen and consist only of carbon and hydrogen
notHydroCarbon(X) :- molecule(X), hasAtom(X,Y), not c(Y), not h(Y).
hydroCarbon(X) :- molecule(X), carbonMolEntity(X), not notHydroCarbon(X).

% molecules that contain carbon, hydrogen and halogen and consist only of carbon, hydrogen and halogen
notHaloHydroCarbon(X) :- molecule(X), hasAtom(X,Y), not c(Y), not h(Y), not halogen(Y).
haloHydroCarbon(X) :- molecule(X), carbonMolEntity(X), halogenMolEntity(X), not notHaloHydroCarbon(X).

% molecules that contain exactly one carbon
atLeast2Carbons(X) :- molecule(X), hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), c(Y2), Y1 != Y2.
exactly1Carbon(X) :- molecule(X), carbonMolEntity(X), not atLeast2Carbons(X).

% molecules that contain exactly two carbons
atLeast3Carbons(X) :- molecule(X), hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), c(Y2), Y1 != Y2, hasAtom(X,Y3), c(Y3), Y1 != Y3, Y2 != Y3.
exactly2Carbons(X) :- atLeast2Carbons(X), not atLeast3Carbons(X).

% molecules that contain exactly three carbons
atLeast4Carbons(X) :- molecule(X), hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), c(Y2), Y1 != Y2, hasAtom(X,Y3), c(Y3), Y1 != Y3, Y2 != Y3, hasAtom(X,Y4), c(Y4), Y1 != Y4, Y2 != Y4, Y3 != Y4.
exactly3Carbons(X) :- atLeast3Carbons(X), not atLeast4Carbons(X).

% molecules that contain exactly four carbons
atLeast5Carbons(X) :- molecule(X), hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), c(Y2), Y1 != Y2, hasAtom(X,Y3), c(Y3), Y1 != Y3, Y2 != Y3, hasAtom(X,Y4), c(Y4), Y1 != Y4, Y2 != Y4, Y3 != Y4, hasAtom(X,Y5), c(Y5), Y1 != Y5, Y2 != Y5, Y3 != Y5, Y4 != Y5.
exactly4Carbons(X) :- atLeast4Carbons(X), not atLeast5Carbons(X).

% molecules that contain at least two atoms
polyatomic(X) :- molecule(X), hasAtom(X,Y1), hasAtom(X,Y2), Y1 != Y2.

% molecules that contains exactly one atom
monoatomic(X) :- molecule(X), hasAtom(X,Y1),not polyatomic(X).

% molecules that contain exactly one carboxy group
%atLeast2CarboxyGroups(X) :- molecule(X), hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), o(Y2), hasAtom(X,Y3), o(Y3), hasAtom(X,Y4), horc(Y4), double(Y1,Y2), double(Y2,Y1), single(Y1,Y3), single(Y3,Y1), single(Y1,Y4), single(Y4,Y1), not midOxygen(Y3), not charged(Y3), hasAtom(X,Y5), c(Y5), hasAtom(X,Y6), o(Y6), hasAtom(X,Y7), o(Y7), hasAtom(X,Y8), horc(Y8), double(Y5,Y6), double(Y6,Y5), single(Y5,Y7), single(Y7,Y5), single(Y5,Y8), single(Y8,Y5), not midOxygen(Y7), not charged(Y7), Y1!=Y5.
%exactly1CarboxyGroup(X) :- acid(X), not atLeast2CarboxyGroups(X).

% molecules that contain exactly two carboxy groups
%atLeast3CarboxyGroups(X) :- molecule(X), hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), o(Y2), hasAtom(X,Y3), o(Y3), hasAtom(X,Y4), horc(Y4), double(Y1,Y2), double(Y2,Y1), single(Y1,Y3), single(Y3,Y1), single(Y1,Y4), single(Y4,Y1), not midOxygen(Y3), not charged(Y3), hasAtom(X,Y5), c(Y5), hasAtom(X,Y6), o(Y6), hasAtom(X,Y7), o(Y7), hasAtom(X,Y8), horc(Y8), double(Y5,Y6), double(Y6,Y5), single(Y5,Y7), single(Y7,Y5), single(Y5,Y8), single(Y8,Y5), not midOxygen(Y7), not charged(Y7), hasAtom(X,Y9), c(Y9), hasAtom(X,Y10), o(Y10), hasAtom(X,Y11), o(Y11), hasAtom(X,Y12), horc(Y12), double(Y9,Y10), double(Y10,Y9), single(Y9,Y11), single(Y11,Y9), single(Y9,Y12), single(Y12,Y9), not midOxygen(Y11), not charged(Y11), Y1!=Y5, Y9!=Y5, Y9!=Y1.
%exactly2CarboxyGroups(X) :- atLeast2CarboxyGroups(X), not atLeast3CarboxyGroups(X).

% molecules that contain a benzene ring
hasBenzeneRing(X) :- molecule(X), hasAtom(X,Y1), c(Y1),  hasAtom(X,Y2), c(Y2), single(Y1,Y2), single(Y2,Y1), hasAtom(X,Y3), c(Y3), double(Y2,Y3), double(Y3,Y2), hasAtom(X,Y4), c(Y4), single(Y3,Y4), single(Y4,Y3), hasAtom(X,Y5), double(Y4,Y5), double(Y5,Y4), c(Y5), hasAtom(X,Y6), c(Y6), single(Y5,Y6), single(Y6,Y5), double(Y6,Y1), double(Y1,Y6).

% molecules that contain a three-membered ring
hasThreeMemberedRing(X) :- hasAtom(X,Y1), hasAtom(X,Y2), Y1 != Y2, bond(Y1,Y2), bond(Y2,Y1), hasAtom(X,Y3), Y1 != Y3,  Y2 != Y3, bond(Y2,Y3), bond(Y3,Y2), bond(Y3,Y1), bond(Y1,Y3).

% molecules that contain a four-membered ring
hasFourMemberedRing(X) :- hasAtom(X,Y1), hasAtom(X,Y2), Y1 != Y2, bond(Y1,Y2), bond(Y2,Y1), hasAtom(X,Y3), Y1 != Y3,  Y2 != Y3, bond(Y2,Y3), bond(Y3,Y2), hasAtom(X,Y4), Y1 != Y4, Y2 != Y4, Y3 != Y4, bond(Y3,Y4), bond(Y4,Y3), bond(Y4,Y1), bond(Y1,Y4).

% organic molecules that are unsaturated
unsaturated(X) :- hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), c(Y2), double(Y1,Y2), double(Y2,Y1).
unsaturated(X) :- hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), c(Y2), triple(Y1,Y2), triple(Y2,Y1).

% organic molecules that are saturated
saturated(X) :- molecule(X), hasAtom(X,Y1), c(Y1), not unsaturated(X).

% organophosphorus molecules
organophosphorus(X) :- hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), p(Y2), single(Y1,Y2), single(Y2,Y1).

% organooxygen molecules
organooxygen(X) :- hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), o(Y2), bond(Y1,Y2), bond(Y2,Y1).

% molecules that contain at least one (possibly acyl) carbon connected with a non-carbon atom
heteroOrganic(X) :- hasAtom(X,Y1), c(Y1), hasAtom(X,Y2), not c(Y2),  not h(Y2), bond(Y1,Y2), bond(Y2,Y1).
