In Boolean algebra, Petrick's method (also known as Petrick function or branch-and-bound method) is a technique described by Stanley R. Petrick (1931–2006) in 1956 for determining all minimum sum-of-products solutions from a prime implicant chart. Petrick's method is very tedious for large charts, but it is easy to implement on a computer. The method was improved by Insley B. Pyne and Edward Joseph McCluskey in 1962.
The algorithm above can be implemented with the C# as shown below:
private string DoPetriksMethod(
Dictionary<string, string> PIchart,
List<string> epis,
List<string> primeImplicants,
List<string> minterms)
{
PIchart = RemoveEPIs(PIchart, epis, minterms);
string minimisedExpression;
Dictionary<char, string> termsImplicantMapping = MapTermsToImplicants(primeImplicants);
List<Bracket> productOfSums = GetProductOfSums(termsImplicantMapping, PIchart);
string[] sumOfproducts = GetSumOfProducts(productOfSums);
string minProduct = GetMinProduct(sumOfproducts);
minimisedExpression = GetFinalExpression(termsImplicantMapping, minProduct);
return minimisedExpression;
}
private static Dictionary<char, string> MapTermsToImplicants(List<string> primeImplicants)
{
var mapping = new Dictionary<char, string>();
char minChar = (char)(primeImplicants[0].Length + 65);
for (var i = 0; i < primeImplicants.Count; i++)
{
mapping.Add(minChar, primeImplicants[i]);
minChar++;
}
return mapping;
}
private static List<Bracket> GetProductOfSums(Dictionary<char, string> termToImplicantMap, Dictionary<string, string> primeImplicantChart)
{
var productOfSums = new List<Bracket>();
List<Bracket> sumsToAdd;
string primeImplicant;
foreach (string key in primeImplicantChart.Keys)
{
primeImplicant = primeImplicantChart[key];
for (var i = 0; i < primeImplicant.Length; i++)
{
if (primeImplicant[i] == '1')
{
sumsToAdd = GetSumsToAdd(primeImplicantChart, termToImplicantMap, key, i);
AddSumsToList(productOfSums, sumsToAdd);
}
}
}
return productOfSums;
}
private static void AddSumsToList(List<Bracket> productOfSums, List<Bracket> sumsToAdd)
{
foreach (Bracket s in sumsToAdd)
{
if (!productOfSums.Contains(s))
{
productOfSums.Add(s);
}
}
}
private static List<Bracket> GetSumsToAdd(Dictionary<string, string> PIchart, Dictionary<char, string> termToImplicantMap, string key, int positionWithinKey)
{
var sumsToAdd = new List<Bracket>();
Bracket sum;
string implicant;
char term1;
char term2;
for (var i = 0; i < PIchart.Keys.Count; i++)
{
implicant = PIchart.Keys.ToArray()[i];
if (PIchart[implicant][positionWithinKey] == '1')
{
term1 = GetTermFromImplicant(termToImplicantMap, key);
term2 = GetTermFromImplicant(termToImplicantMap, implicant);
if (term1 != term2)
{
sum = new Bracket(term1, term2);
sumsToAdd.Add(sum);
}
}
}
return sumsToAdd;
}
private static char GetTermFromImplicant(Dictionary<char, string> termToImplicantMap, string implicant)
{
string[] implicants = termToImplicantMap.Values.ToArray();
char[] keys = termToImplicantMap.Keys.ToArray();
for (var i = 0; i < termToImplicantMap.Values.Count; i++)
{
if (implicants[i] == implicant)
{
return keys[i];
}
}
throw new Exception("Could not map implicant to key");
}
private static string[] GetSumOfProducts(List<Bracket> productOfSums)
{
Bracket b1;
Bracket b2;
Bracket mergedTerm;
bool merged = true;
while (merged)
{
merged = false;
for (var i = 0; i < productOfSums.Count - 1; i++)
{
for (var c = i + 1; c < productOfSums.Count; c++)
{
b1 = productOfSums[i];
b2 = productOfSums[c];
if (b1.term1 == b2.term1 != (b1.term2 == b2.term2) != (b1.term1 == b2.term2) != (b1.term2 == b2.term1))
{
mergedTerm = MergeBrackets(b1, b2);
productOfSums.Add(mergedTerm);
productOfSums.Remove(b1);
productOfSums.Remove(b2);
merged = true;
i = c + 1;
c = i + 1;
}
}
}
}
List<List<string>> stringProducts = ConvertBracketsToString(productOfSums);
List<List<string>> sumOfProducts = RecursiveDistributiveLaw(stringProducts);
return sumOfProducts[0].ToArray();
}
private static Bracket MergeBrackets(Bracket b1, Bracket b2)
{
var b = new Bracket();
if (b1.term1 == b2.term1)
{
b.term1 = b1.term1;
b.term2 = b1.term2 + b2.term2;
return b;
}
else
{
b.term1 = b1.term2;
b.term2 = b1.term1 + b2.term2;
return b;
}
}
private static List<List<string>> ConvertBracketsToString(List<Bracket> brackets)
{
var result = new List<List<string>>();
List<string> tmp;
foreach (Bracket b in brackets)
{
tmp = new List<string> { b.term1, b.term2 };
result.Add(tmp);
}
return result;
}
private static List<List<string>> RecursiveDistributiveLaw(List<List<string>> brackets)
{
var lls = new List<List<string>>();
if (brackets.Count > 1)
{
lls.Add(SingleDistributiveLaw(brackets[0], brackets[1]));
brackets.RemoveAt(0);
brackets.RemoveAt(0);
lls.AddRange(brackets);
return RecursiveDistributiveLaw(lls);
}
else
{
return brackets;
}
}
private static List<string> SingleDistributiveLaw(List<string> b1, List<string> b2)
{
var lls = new List<string>();
for (var i = 0; i < b1.Count; i++)
{
for (var j = 0; j < b2.Count; j++)
{
lls.Add(ApplyDistributiveLaw(b1[i], b2[j]));
}
}
return lls;
}
private static string ApplyDistributiveLaw(string a, string b)
{
string tempResult = a + b;
string finalResult = "";
foreach (char c in tempResult)
{
if (!finalResult.Contains(c))
{
finalResult += c;
}
}
return finalResult;
}
private static string GetMinProduct(string[] sumOfProducts)
{
string minProduct = sumOfProducts[0];
foreach (string p in sumOfProducts)
{
if (p.Length < minProduct.Length)
{
minProduct = p;
}
}
return minProduct;
}
private string GetFinalExpression(Dictionary<char, string> termToImplicantMap, string minProduct)
{
string subExpression;
string implicant;
string result = "";
for (var i = 0; i < minProduct.Length; i++)
{
implicant = termToImplicantMap[minProduct[i]];
subExpression = ConvertImplicantToExpression(implicant);
result += subExpression;
if (i < minProduct.Length - 1)
{
result += " + ";
}
}
return result;
}
The following code snippet assumes access to the bracket struct.
struct Bracket
{
public Bracket(char term1, char term2)
{
// Sorting into alphabetical order. This can be done as OR is commutative.
if (term1 < term2)
{
this.term1 = term1.ToString();
this.term2 = term2.ToString();
}
else
{
this.term1 = term2.ToString();
this.term2 = term1.ToString();
}
}
// The two terms that make up the brackets. These are assigned to when the
// product of sums is created in Petrick's method.
public string term1;
public string term2;
}
Following is the function we want to reduce:
The prime implicant chart from the Quine-McCluskey algorithm is as follows:
| 0 | 1 | 2 | 5 | 6 | 7 | ⇒ | A | B | C | |
|---|---|---|---|---|---|---|---|---|---|---|
| K = m(0,1) | ⇒ | 0 | 0 | — | ||||||
| L = m(0,2) | ⇒ | 0 | — | 0 | ||||||
| M = m(1,5) | ⇒ | — | 0 | 1 | ||||||
| N = m(2,6) | ⇒ | — | 1 | 0 | ||||||
| P = m(5,7) | ⇒ | 1 | — | 1 | ||||||
| Q = m(6,7) | ⇒ | 1 | 1 | — |
Based on the ✓ marks in the table above, build a product of sums of the rows. Each column of the table makes a product term which adds together the rows having a ✓ mark in that column:
(K+L)(K+M)(L+N)(M+P)(N+Q)(P+Q)
Use the distributive law to turn that expression into a sum of products. Also use the following equivalences to simplify the final expression: X + XY = X and XX = X and X + X = X
= (K+L)(K+M)(L+N)(M+P)(N+Q)(P+Q) = (K+LM)(N+LQ)(P+MQ) = (KN+KLQ+LMN+LMQ)(P+MQ) = KNP + KLPQ + LMNP + LMPQ + KMNQ + KLMQ + LMNQ + LMQ
Now use again the following equivalence to further reduce the equation: X + XY = X
= KNP + KLPQ + LMNP + LMQ + KMNQ
Choose products with fewest terms, in this example, there are two products with three terms:
KNP LMQ
Referring to the prime implicant table, transform each product by replacing prime implicants with their expression as boolean variables, and substitute a sum for the product. Then choose the result which contains the fewest total literals (boolean variables and their complements). Referring to our example:
KNP expands to A'B' + BC' + AC where K converts to A'B', N converts to BC', etc. LMQ expands to A'C' + B'C + AB
Both products expand to six literals each, so either one can be used. In general, application of Petrick's method is tedious for large charts, but it is easy to implement on a computer.
Stanley R. Petrick was born in Cedar Rapids, Iowa on August 16, 1931. He attended the Roosevelt High School and received a B. S. degree in Mathematics from the Iowa State University in 1953. During 1953 to 1955 he attended MIT while on active duty as an Air Force officer and received the S. M. degree from the Department of Electrical Engineering in 1955. He was elected to Sigma Xi in 1955.
Mr. Petrick has been associated with the Applied Mathematics Board of the Data Sciences Laboratory at the Air Force Cambridge Research Laboratories since 1955 and his recent studies at MIT have been partially supported by AFCRL. During 1959–1962 he held the position of Lecturer in Mathematics in the Evening Graduate Division of Northeastern University.
Mr. Petrick is currently a member of the Linguistic Society of America, The Linguistic Circle of New York, The American Mathematical Association, The Association for Computing Machinery, and the Association for Machine Translation and Computational Linguistics.
[...] CEDAR RAPIDS Stanley R. Petrick, 74, formerly of Cedar Rapids, died July 27, 2006, in Presbyterian/St. Luke's Hospital, Denver, Colo., following a 13-year battle with leukemia. A memorial service will be held Aug. 14 at the United Presbyterian Church in Laramie, Wyo., where he lived for many years. [...] Stan Petrick was born in Cedar Rapids on Aug. 6, 1931 to Catherine Hunt Petrick and Fred Petrick. He graduated from Roosevelt High School in 1949 and received a B.S. degree in mathematics from Iowa State University. Stan married Mary Ethel Buxton in 1953.(NB. Includes a photo of Stanley R. Petrick.)
He joined the U.S. Air Force and was assigned as a student officer studying digital computation at MIT, where he earned an M.S. degree. He was then assigned to the Applied Mathematics Branch of the Air Force Cambridge Research Laboratory and while there earned a Ph.D. in linguistics.
He spent 20 years in the Theoretical and Computational Linguistics Group of the Mathematical Sciences Department at IBM's T. J. Watson Research Center, conducting research in formal language theory. He had served as an assistant director of the Mathematical Sciences Department, chairman of the Special Interest Group on Symbolic and Algebraic Manipulation of the Association for Computing Machinery and president of the Association for Computational Linguistics. He authored many technical publications.
He taught three years at Northeastern University and 13 years at the Pratt Institute. Dr. Petrick joined the University of Wyoming in 1987, where he was instrumental in developing and implementing the Ph.D. program in the department and served as a thesis adviser for many graduate students. He retired in 1995. [...]
{{cite book}}: More than one of |location= and |publication-place= specified (help) (xiv+379+1 pages)