The Ternary Algebra of Vegan Status

The algebra of yes, no, maybe determining ingredients' vegan status.

Posted on: 18 Mar 2026

Introduction

All ingredients in the database have one of three possible vegan classifications:

Vegan

This ingredient is commercially available only in a form which is produced synthetically or derived from plants or inorganic material.

Maybe Vegan

This ingredient may be derived from either animal or vegan sources.

Not Vegan

This ingredient is derived from animal products.

At some point I thought about including a "typically vegan" classification for ingredients like riboflavin and niacin since the commercial supply is almost entirely vegan, but decided against it since I thought it would add too much complexity to the database and it wasn't clear exactly what the threshold should be.

The database schema for the ingredients in the vegandex database has gone through several iterations as I've progressed. Initially the ingredients were stored in a very simple CSV file with integers representing whether the ingredient was vegan, maybe vegan, or not vegan. It looked something like this:

# name, vegan, vegetarian
water,1,1
salt,1,1
citric acid,1,1
natural flavors,0,0
honey,-1,1
where 1 represents vegan, 0 represents maybe vegan, and -1 represents not vegan. Using integers in this way is convenient because later when we want to compute whether a product is vegan we can simply compute the minimum of all the ingredients' vegan status. Later, because of the sheer number of different spellings and misspellings for the same ingredient, I realized it was necessary to have some way to map an ingredient to another ingredient (see Ways to Misspell an Ingredient). I initially achieved this with another CSV file that just mapped names to names which looked like:
# name, primary name
sea salt,salt
sea sal,salt
natural flavor,natural flavors
garlic powder,garlic
garlic powders,garlic
organic natural flavor,natural flavors
organic flavor,natural flavors
organic spices,spices
spice,spices
herbs & spices,spices
himalayan pink salt,salt

At some point I added the ability for users to change the vegan status of ingredients in their local copy of the database. This was done because there are several ingredients like riboflavin and niacin for which the commercial supply is almost entirely vegan, but there are a handful of niche manufacturers that still manufacture them from animals (see this article from the VRG). These ingredients are in lots of products and so it makes sense to allow people to change these based on their individual tolerance.

Since users now have the ability to change the vegan status of ingredients it is necessary to propagate these changes to ingredients which are manufactured from them. For example, sugar can be made from cane sugar or beet sugar. If the user changes the vegan status of cane sugar, it is necessary to also change the vegan status of sugar. This necessitated a fairly large change to the database and made me think about the mathematics behind how the vegan status should be calculated.

The Mathematics of Vegan Status

Ingredients can derive from other ingredients in one of two ways. Let's consider a hypothetical ingredient C which depends on ingredients A and B. First, ingredient C can be made from ingredient A and ingredient B. In this case, the ingredient C's vegan status would be

A and B Y N M
Y Y N M
N N N N
M M N M

Second, ingredient C could be made from ingredient A or ingredient C. In this case ingredient C's vegan status would be:

A or B Y N M
Y Y M M
N M N M
M M M M

where Y stands for vegan, N stands for not vegan, and M stands for maybe vegan.

With these "truth tables" we can then calculate the vegan status of ingredients which depend on others in more complicated ways. For example: hexanal is made from 1-pentene or (caproic acid and formic acid). To calculate it's vegan status:

hexanal = 1-pentene or (caproic acid and formic acid)
hexanal = Y or (M and Y)
hexanal = Y or M
hexanal = M

and therefore it's vegan status is maybe (which means it can be derived from either animal or vegan sources). For most of these cosmetic ingredients, it's largely irrelevant since there are so many ingredients that may or may not be vegan that the overall vegan status based on ingredients is almost always maybe. However, this system makes it a lot nicer to handle ingredients related to sugar for example. The ingredients related to sugar now look something like:

# name, vegan, vegetarian, derives_from
cane sugar,1,1,,
sugar (vegan),1,1,,
sugarcane,1,1,,
beet sugar,,,beets
sugar,,,cane sugar or beet sugar
cultured sugar,,,sugar and bacteria,,,
cultured sugar (vegan),,,sugar (vegan) and bacteria
organic sugar,,,sugar (vegan)
molasses,,,sugar
molasses (vegan),,,sugar (vegan)
caramel color,,,corn or cane sugar
glucose,,,sugar
sucrose,,,sugar
So now if someone wants to treat cane sugar as maybe non-vegan they only have to change the ingredient for "cane sugar" instead of all the other ingredients.