**Truthtab**
capture program drop truthtab
program define truthtab, rclass
version 9.0
syntax [namelist] [, OUTSHeet(string) indvars(namelist) FROMREDuce(namelist)]
preserve
unab vlist: _all

if "`c(more)'"== "on" {
	set more off
	local iset off
	}

if "`namelist'" ~= "" {
	local y: word 1 of `namelist'
	local sets: list namelist - y

	if "`indvars'" == "" {
	 local nonvar: list sets - vlist
            foreach con of local nonvar {
		   cnfgen `con'
	      }
	local indvars `r(letters)'
	}

	local num: word count `sets'
	local length: word count `indvars'
	local fc = `length' + 1
	local cols "`indvars' `y'"
	matrix truthtab = J(`num',`fc',0)
    unab sets: `sets'
}

foreach var of local sets {
	qui su `var'
	if `r(max)' > 1 | `r(min)'<0 {
		di as err "Error: `var' Not Fuzzified"
		capture keep `vlist'
		exit 119
	}
}

if "`namelist'" == "" {
	local sets = r(sets)
	local start = r(start)
	local y = r(y)
	local lastset `r(colsig)'
	if "`r(comm)'" ~= "" {
		 local lastset `r(comm)'
		}
	qui capture myboolean `start'
 	local sets `lastset'
	if "`sets'" == "" {
		di
		di as err "Error: No Configurations Identified"
		capture keep `vlist'
		exit
    	}
	unab sets: `sets'
	local num: word count `sets'
	local length: word count `start'
	local fc = `length' + 1
	matrix truthtab = J(`num',`fc',0)
	local cols "`start' `y'"
}

local i 1
foreach var of local sets {
	local z=1
		forvalues j = 1/`length' {
			local `var'prt= substr("`var'", `j', 1)
			local configz`z' = "``var'prt'"
			local upper`var' = upper("`configz`z''")
		    if "`configz`z''" == "`upper`var''" {
			matrix truthtab[`i', `z'] = 1
		    }
		    if "`configz`z''" ~= "`upper`var''" {
			matrix truthtab[`i', `z'] = 0
		    }
		local z = `z' +1
		}
	matrix truthtab [`i', `fc'] = 1
	local ++i
	}

matrix colnames truthtab = "`cols'"
local numberfinsols: word count `fromreduce'
if `numberfinsols' == 0 {
	matlist truthtab, format(%9.3f)
}
qui drop _all
qui svmat truthtab, names(col)
local numberfinsols: word count `fromreduce'
if `numberfinsols' == 0 & "`outsheet'"~="" {
qui outsheet using "`outsheet'", nol c replace
}

if `numberfinsols' > 0 {
	drop `y'
	foreach ttvar of local indvars {
		rename `ttvar' __`ttvar'
		}
	qui foreach nv of local fromreduce {
		gen `nv' = 0
		local `nv' "`nv'"
		local ln`nv': length local `nv'
		local z 1
			forvalues j = 1/`ln`nv'' {
				local `nv'prt= substr("`nv'", `j', 1)
				local configz`z' = "``nv'prt'"
				local upper`nv' = upper("`configz`z''")
			   		local restrict "& __`upper`nv''=="
		 				if "`configz`z''" == "`upper`nv''" {
							local restrict `restrict' 1
		    				}
		    				if "`configz`z''" ~= "`upper`nv''" {
						local restrict `restrict' 0
		    				}
				local z = `z' +1
				local condition `condition' `restrict'
			}
	local condition:subinstr local condition "&" ""
	replace `nv' = 1 if `condition'
	local condition
	}

egen sum = rsum(`fromreduce')
	qui foreach nv of local fromreduce {
		recode `nv' (1=100) if sum==1
		su `nv'
		if r(max)==100 {
			recode `nv' (1=100)
			local primes `primes' `nv'
		}
	}
qui egen rowmax = rsum(`fromreduce')
local unnec: list fromreduce - primes
local numunnec: word count `unnec'
	if `numunnec' ~= 0 {
		qui drop if rowmax>=100
		qui drop `primes' rowmax
		qui egen rowmax = rsum(`unnec')
		qui su rowmax
			if `r(N)' == 0 {
				local finalsols `primes'
			}
			else {
			qui foreach unv of local unnec {
				 su `unv'
					if `r(sum)'==`r(N)' & `r(N)'~=1 {
					  local finalsols `primes' `unv'
					 }
					if `r(N)' == 1 {
						local leftover `unnec'
						local finalsols `primes'
					}
				}
			}
	}
	else {
		local finalsols `primes'
	}
	local needwork: word count `finalsols'
		if `needwork'==0 {
			qui foreach unv of local unnec {
				su `unv'
				local `unv'sum = r(sum)
			}
			tokenize `unnec'
			local numleft: word count `unnec'
			local mgen 0
			qui forvalues i = 1/`=`numleft'-1' {
				qui forvalues k = `=`i'+1'/`numleft' {
					local maxcom = ```i''sum' + ```k''sum'
					if `maxcom' > `mgen' {
						local mgen `maxcom'
						local mgencs ``i'' ``k''
				   	}
				}
			}
		   local finalsols `primes' `mgencs'
		}
}
restore
if "`iset'" == "off" {
	set more on
	}

return local leftover `leftover'
return local finsols `finalsols'
return local start `start'
return local sets `sets'
return local y `y'
capture keep `vlist'
end