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 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).
