#!/bin/bash
#calc_functions
# Copyright (c) 2008 Graham Petley
# Released under the terms of the GNU Lesser General Public Licence

# The script counts the number of unique functions that can be made
# from 1-4 inputs. The functions are given as the Sum of Product (SOP)
# terms. A term is either the SOP or inverse Product of Sum.

# The script loops thru the max number of SOP terms and increments
# each SOP. Successive SOPs must be different and have a higher value.
# For each candidate function, the bits of the product terms are
# rotated to find the first numeric sequence. For example, take the
# function z=0001+0110+1001

# swap bits 1 and 3; then reorder
# 0001   0001   0001
# 0110 > 1100 > 0011
# 1001   0011   1100

# The starting sequence z=0001+0110+1001 is discarded because the new
# sequence  z=0001+001+1100 is numerically smaller. In this way
# duplicate functions made up of the same SOPs with the bits in a
# different sequence are removed.

# For 1-3 input functions, all the possible functions are listed with
# their pharosc names. Some of the 4 input functions have their
# pharosc names.

# The result is
# Number of inputs     1    2    3    4
# Number of functions  4   12   80 3984

# The function list is written to standard output and the summary
# total to error output.

if [ "$#" -eq 0 ]
then
  req_inputs='1 2 3 4'
else
  if [ "$1" -ne 1 -a "$1" -ne 2 -a "$1" -ne 3 -a "$1" -ne 4 ]
  then
    echo "# Only 1,2,3 or 4 inputs supported right now" 1>&2
    exit 1
  fi
  req_inputs=$1
fi

max_inputs=4
num_func=0

print_sops()
{
# Output list of SOP terms in arg_1 and pharosc name if exists
case $1 in
  0)
#   0 SOP terms (VSS and VDD connexions)
    case $num_inputs in
      1)
        let "num_func=num_func+1"; printf "%1d" $num_func; echo " vddtie"
        let "num_func=num_func+1"; printf "%1d" $num_func; echo " vsstie" ;;
      2|3)
        let "num_func=num_func+1"; printf "%2d" $num_func; echo " vddtie"
        let "num_func=num_func+1"; printf "%2d" $num_func; echo " vsstie" ;;
      4)
        let "num_func=num_func+1"; printf "%3d" $num_func; echo " vddtie"
        let "num_func=num_func+1"; printf "%3d" $num_func; echo " vsstie" ;;
      *)
        let "num_func=num_func+1"; printf "%4d" $num_func; echo " vddtie"
        let "num_func=num_func+1"; printf "%4d" $num_func; echo " vsstie" ;;
    esac ;;
  1)
#   1 SOP term
    case $num_inputs in
      1)
        case $minsop1 in
          0000) let "num_func=num_func+1"; printf "%1d" $num_func; echo " iv1         $minsop1" ;;
          0001) let "num_func=num_func+1"; printf "%1d" $num_func; echo " bf1         $minsop1" ;;
          *)    let "num_func=num_func+1"; printf "%1d" $num_func; echo "             $minsop1" ;;
        esac ;;
      2)
        case $minsop1 in
          0000) let "num_func=num_func+1"; printf "%2d" $num_func; echo " nr2        $minsop1"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " or2        not ($minsop1)" ;;
          0001) let "num_func=num_func+1"; printf "%2d" $num_func; echo " nr2a       $minsop1"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " nd2a       not ($minsop1)" ;;
          0011) let "num_func=num_func+1"; printf "%2d" $num_func; echo " an2        $minsop1"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " nd2        not ($minsop1)" ;;
          *)    let "num_func=num_func+1"; printf "%2d" $num_func; echo "            $minsop1"; let "num_func=num_func+1"; printf "%2d" $num_func; echo "            not ($minsop1)" ;;
        esac ;;
      3)
        case $minsop1 in
          0000) let "num_func=num_func+1"; printf "%2d" $num_func; echo " nr3        $minsop1"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " or3        not ($minsop1)" ;;
          0001) let "num_func=num_func+1"; printf "%2d" $num_func; echo " nr3a       $minsop1"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " nd3ab      not ($minsop1)" ;;
          0011) let "num_func=num_func+1"; printf "%2d" $num_func; echo " nr3ab      $minsop1"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " nd3a       not ($minsop1)" ;;
          0111) let "num_func=num_func+1"; printf "%2d" $num_func; echo " an3        $minsop1"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " nd3        not ($minsop1)" ;;
          *)    let "num_func=num_func+1"; printf "%2d" $num_func; echo "            $minsop1"; let "num_func=num_func+1"; printf "%2d" $num_func; echo "            not ($minsop1)" ;;
        esac ;;
      4)
        case $minsop1 in
          0000) let "num_func=num_func+1"; printf "%4d" $num_func; echo " nr4        $minsop1"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " or4        not ($minsop1)" ;;
          0001) let "num_func=num_func+1"; printf "%4d" $num_func; echo " nr4a       $minsop1"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " nd4abc     not ($minsop1)" ;;
          0011) let "num_func=num_func+1"; printf "%4d" $num_func; echo " nr4ab      $minsop1"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " nd4ab      not ($minsop1)" ;;
          0111) let "num_func=num_func+1"; printf "%4d" $num_func; echo " nr4abc     $minsop1"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " nd4a       not ($minsop1)" ;;
          1111) let "num_func=num_func+1"; printf "%4d" $num_func; echo " an4        $minsop1"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " nd4        not ($minsop1)" ;;
          *)    let "num_func=num_func+1"; printf "%4d" $num_func; echo "            $minsop1"; let "num_func=num_func+1"; printf "%4d" $num_func; echo "            not ($minsop1)" ;;
        esac ;;
      *)
          let "num_func=num_func+1"; printf "%7d" $num_func; echo "            $minsop1"; let "num_func=num_func+1"; printf "%7d" $num_func; echo "            not ($minsop1)" ;;
    esac ;;
  2)
#   2 SOP terms
    case $num_inputs in
      2)
        case $minsop1' '$minsop2 in
          '0000 0001') let "num_func=num_func+1"; printf "%2d" $num_func; echo " iv1        $minsop1+$minsop2" ;;
          '0000 0011') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnr2       $minsop1+$minsop2" ;;
          '0001 0010') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xor2       $minsop1+$minsop2" ;;
          '0001 0011') let "num_func=num_func+1"; printf "%2d" $num_func; echo " bf1        $minsop1+$minsop2" ;;
          *)           let "num_func=num_func+1"; printf "%2d" $num_func; echo "            $minsop1+$minsop2" ;;
        esac ;;
      3)
        case $minsop1' '$minsop2 in
          '0000 0001') let "num_func=num_func+1"; printf "%2d" $num_func; echo " nr2        $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " or2        not ($minsop1+$minsop2)" ;;
          '0000 0011') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xroi21     $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xron21     not ($minsop1+$minsop2)" ;;
          '0000 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xroi22u1   $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xron22u1   not ($minsop1+$minsop2)" ;;
          '0001 0010') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnoi21     $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnon21     not ($minsop1+$minsop2)" ;;
          '0001 0011') let "num_func=num_func+1"; printf "%2d" $num_func; echo " nr2a       $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " nd2a       not ($minsop1+$minsop2)" ;;
          '0001 0110') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xran22u1   $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xrai22u1   not ($minsop1+$minsop2)" ;;
          '0001 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnan21     $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnai21     not ($minsop1+$minsop2)" ;;
          '0011 0101') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xran21     $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xrai21     not ($minsop1+$minsop2)" ;;
          '0011 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " an2        $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " nd2        not ($minsop1+$minsop2)" ;;
          *)           let "num_func=num_func+1"; printf "%2d" $num_func; echo "            $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%2d" $num_func; echo "            not ($minsop1+$minsop2)" ;;
        esac ;;
      4)
        case $minsop1' '$minsop2 in
          '0000 0001') let "num_func=num_func+1"; printf "%4d" $num_func; echo " nr3        $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " or3        not ($minsop1+$minsop2)" ;;
          '0000 0011') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xroi211    $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xron211    not ($minsop1+$minsop2)" ;;
          '0001 0010') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnoi211    $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnon211    not ($minsop1+$minsop2)" ;;
          '0001 0011') let "num_func=num_func+1"; printf "%4d" $num_func; echo " nr3a       $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " nd3ab      not ($minsop1+$minsop2)" ;;
          '0001 0111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnan211b   $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnai211b   not ($minsop1+$minsop2)" ;;
          '0011 0101') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xran211b   $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xrai211b   not ($minsop1+$minsop2)" ;;
          '0011 0111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " nr3ab      $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " nd3a       not ($minsop1+$minsop2)" ;;
          '0011 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnan211    $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnai211    not ($minsop1+$minsop2)" ;;
          '0111 1011') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xran211    $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xrai211    not ($minsop1+$minsop2)" ;;
          '0111 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " an3        $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " nd3        not ($minsop1+$minsop2)" ;;
          *)           let "num_func=num_func+1"; printf "%4d" $num_func; echo "            $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%4d" $num_func; echo "            not ($minsop1+$minsop2)" ;;
        esac ;;
      *)
        let "num_func=num_func+1"; printf "%7d" $num_func; echo "            $minsop1+$minsop2"; let "num_func=num_func+1"; printf "%7d" $num_func; echo "            not ($minsop1+$minsop2)" ;;
    esac ;;
  3)
#   3 SOP terms
    case $num_inputs in
      3)
        case $minsop1' '$minsop2' '$minsop3 in
          '0000 0001 0010') let "num_func=num_func+1"; printf "%2d" $num_func; echo " aoi21      $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " aon21      not ($minsop1+$minsop2+$minsop3)" ;;
          '0000 0001 0011') let "num_func=num_func+1"; printf "%2d" $num_func; echo " aoi21a2    $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " oai21a2b   not ($minsop1+$minsop2+$minsop3)" ;;
          '0000 0001 0110') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xraoi22u1  $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xraon22u1  not ($minsop1+$minsop2+$minsop3)" ;;
          '0000 0001 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xraoi22b   $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xraon22b   not ($minsop1+$minsop2+$minsop3)" ;;
          '0000 0011 0101') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xroi32     $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xron32     not ($minsop1+$minsop2+$minsop3)" ;;
          '0000 0011 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xraoi22a1  $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xraon22a1  not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0010 0100') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnoi32     $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnon32     not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0010 0011') let "num_func=num_func+1"; printf "%2d" $num_func; echo " oan21b     $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " oan21b     not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0010 0101') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnaoi22u1  $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnaon22u1  not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0010 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xran32     $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xrai32     not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0011 0101') let "num_func=num_func+1"; printf "%2d" $num_func; echo " aoi21b     $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " aon21b     not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0011 0110') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xroan22    $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xroai22    not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0011 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " oan21a1    $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " oai21a1    not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0110 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnoan22    $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnoai22    not ($minsop1+$minsop2+$minsop3)" ;;
          '0011 0101 0110') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnan32     $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnai32     not ($minsop1+$minsop2+$minsop3)" ;;
          '0011 0101 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " oan21      $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo " oai21      not ($minsop1+$minsop2+$minsop3)" ;;
          *)                let "num_func=num_func+1"; printf "%2d" $num_func; echo "            $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%2d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3)" ;;
        esac ;;
      4)
        case $minsop1' '$minsop2' '$minsop3 in
          '0000 0001 0010') let "num_func=num_func+1"; printf "%4d" $num_func; echo " aoi211     $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " aon211     not ($minsop1+$minsop2+$minsop3)" ;;
          '0000 0001 0011') let "num_func=num_func+1"; printf "%4d" $num_func; echo " aoi211a2   $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " aon211a2   not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0010 0011') let "num_func=num_func+1"; printf "%4d" $num_func; echo " aoi211a    $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " aon211a    not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0011 0101') let "num_func=num_func+1"; printf "%4d" $num_func; echo " aoi211b    $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " aon211b    not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0011 0111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " aoi211a2b  $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " aon211a2b  not ($minsop1+$minsop2+$minsop3)" ;;
          '0011 0101 0111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " oan211b    $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " oai211b    not ($minsop1+$minsop2+$minsop3)" ;;
          '0011 0111 1011') let "num_func=num_func+1"; printf "%4d" $num_func; echo " aoi211bc   $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " aon211bc   not ($minsop1+$minsop2+$minsop3)" ;;
          '0011 0111 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " oan211a2   $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " oai211a2   not ($minsop1+$minsop2+$minsop3)" ;;
          '0111 1011 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " oan211     $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " oai211     not ($minsop1+$minsop2+$minsop3)" ;;
          *)                let "num_func=num_func+1"; printf "%4d" $num_func; echo "            $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%4d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3)" ;;
        esac ;;
      *)
        let "num_func=num_func+1"; printf "%7d" $num_func; echo "            $minsop1+$minsop2+$minsop3"; let "num_func=num_func+1"; printf "%7d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3)" ;;
    esac ;;
  4)
#   4 SOP terms
    case $num_inputs in
      3)
        case $minsop1' '$minsop2' '$minsop3' '$minsop4 in
          '0000 0001 0010 0011') let "num_func=num_func+1"; printf "%2d" $num_func; echo " iv1        $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0000 0001 0010 0100') let "num_func=num_func+1"; printf "%2d" $num_func; echo " cgi2       $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0000 0001 0010 0101') let "num_func=num_func+1"; printf "%2d" $num_func; echo " mxi2       $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0000 0001 0010 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xaoi21     $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0000 0001 0011 0101') let "num_func=num_func+1"; printf "%2d" $num_func; echo " cgi2c      $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0000 0001 0011 0110') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xaoi21a2   $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0000 0001 0011 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " mxi2a1     $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0000 0001 0110 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnr2       $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0000 0011 0101 0110') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xnr3       $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0000 0011 0101 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xooi21     $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0001 0010 0011 0100') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xoon21     $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0001 0010 0011 0101') let "num_func=num_func+1"; printf "%2d" $num_func; echo " mxi2a0     $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0001 0010 0011 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " cgi2ab     $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0001 0010 0100 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xor3       $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0001 0010 0101 0110') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xor2       $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0001 0010 0101 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xaon21a2   $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0001 0011 0101 0110') let "num_func=num_func+1"; printf "%2d" $num_func; echo " xaon21     $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0001 0011 0101 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " bf1        $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0001 0011 0110 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " mxn2       $minsop1+$minsop2+$minsop3+$minsop4" ;;
          '0011 0101 0110 0111') let "num_func=num_func+1"; printf "%2d" $num_func; echo " cgn2       $minsop1+$minsop2+$minsop3+$minsop4" ;;
          *)                     let "num_func=num_func+1"; printf "%2d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4" ;;
        esac ;;
      4)
        case $minsop1' '$minsop2' '$minsop3' '$minsop4 in
          '0000 0001 0010 0011') let "num_func=num_func+1"; printf "%4d" $num_func; echo " nr2        $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " or2        not ($minsop1+$minsop2+$minsop3)" ;;
          '0000 0001 0110 0111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xroi21     $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xron21     not ($minsop1+$minsop2+$minsop3)" ;;
          '0000 0001 1110 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xroi22u1   $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xron22u1   not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0010 0011 0111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " cgi2coi2   $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " cgi2coi2   not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0010 0101 0110') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnoi21     $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnon21     not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0011 0101 0111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " nr2a       $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " nd2a       not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0011 1100 1110') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xron22u1   $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xroi22u1   not ($minsop1+$minsop2+$minsop3)" ;;
          '0001 0011 1101 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnan21     $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnai21     not ($minsop1+$minsop2+$minsop3)" ;;
          '0011 0101 0110 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " cgi2oi2    $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " cgi2on2    not ($minsop1+$minsop2+$minsop3)" ;;
          '0011 0101 1011 1101') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xran21     $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xrai21     not ($minsop1+$minsop2+$minsop3)" ;;
          '0011 0111 1011 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " an2        $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " nd2        not ($minsop1+$minsop2+$minsop3)" ;;
          '0111 1011 1101 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " cgn2an2    $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " cgn2ai2    not ($minsop1+$minsop2+$minsop3)" ;;
          *)                     let "num_func=num_func+1"; printf "%4d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%4d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3+$minsop4)" ;;
        esac ;;
      *)
        let "num_func=num_func+1"; printf "%7d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4"; let "num_func=num_func+1"; printf "%7d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3+$minsop4)" ;;
    esac ;;
  5)
#   5 SOP terms
    case $num_inputs in
      4)
        case $minsop1' '$minsop2' '$minsop3' '$minsop4' '$minsop5 in
          '0000 0001 0010 0011 0100') let "num_func=num_func+1"; printf "%4d" $num_func; echo " o2aoi21    $minsop1+$minsop2+$minsop3+$minsop4+$minsop5"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " o2aon21    not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5)" ;;
          '0011 0111 1011 1101 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " a2oan21    $minsop1+$minsop2+$minsop3+$minsop4+$minsop5"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " a2oai21    not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5)" ;;
          *)                          let "num_func=num_func+1"; printf "%4d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4+$minsop5"; let "num_func=num_func+1"; printf "%4d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5)" ;;
        esac ;;
      *)
        let "num_func=num_func+1"; printf "%7d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4+$minsop5"; let "num_func=num_func+1"; printf "%7d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5)" ;;
    esac ;;
  6)
#   6 SOP terms
    case $num_inputs in
      4)
        case $minsop1' '$minsop2' '$minsop3' '$minsop4' '$minsop5' '$minsop6 in
          '0000 0001 0010 0011 0100 0101') let "num_func=num_func+1"; printf "%4d" $num_func; echo " aoi21      $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " aon21      not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6)" ;;
          '0001 0010 0011 0100 1000 1100') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xoon22     $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xooi22     not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6)" ;;
          '0011 0101 0111 1011 1101 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " oan21      $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " oai21      not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6)" ;;
          '0011 0111 1011 1100 1101 1110') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xaon22     $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " xaoi22     not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6)" ;;
          *)                               let "num_func=num_func+1"; printf "%4d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6"; let "num_func=num_func+1"; printf "%4d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6)" ;;
        esac ;;
      *)
        let "num_func=num_func+1"; printf "%7d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6"; let "num_func=num_func+1"; printf "%7d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6)" ;;
    esac ;;
  7)
#   7 SOP terms
    case $num_inputs in
      4)
        case $minsop1' '$minsop2' '$minsop3' '$minsop4' '$minsop5' '$minsop6' '$minsop7 in
          '0000 0001 0010 0011 0100 0101 0110') let "num_func=num_func+1"; printf "%4d" $num_func; echo " aoi31      $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " aon31      not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7)" ;;
          '0000 0001 0010 0011 0100 1000 1100') let "num_func=num_func+1"; printf "%4d" $num_func; echo " oai22      $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " oan22      not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7)" ;;
          '0011 0101 0111 1001 1011 1101 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " oan31      $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " oai31      not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7)" ;;
          '0011 0111 1011 1100 1101 1110 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " aon22      $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7"; let "num_func=num_func+1"; printf "%4d" $num_func; echo " aoi22      not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7)" ;;
          *)                                    let "num_func=num_func+1"; printf "%4d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7"; let "num_func=num_func+1"; printf "%4d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7)" ;;
        esac ;;
      *)
        let "num_func=num_func+1"; printf "%7d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7"; let "num_func=num_func+1"; printf "%7d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7)" ;;
    esac ;;
  8)
#   8 SOP terms
    case $num_inputs in
      4)
        case $minsop1' '$minsop2' '$minsop3' '$minsop4' '$minsop5' '$minsop6' '$minsop7' '$minsop8 in
          '0000 0001 0010 0011 0100 0101 0110 0111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " iv1        $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0000 0001 0010 0011 0100 0101 0110 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xaoi31     $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0000 0001 0010 0011 0100 0101 1000 1001') let "num_func=num_func+1"; printf "%4d" $num_func; echo " cgi2       $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0000 0001 0010 0011 0100 0101 1100 1101') let "num_func=num_func+1"; printf "%4d" $num_func; echo " mxi2       $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0000 0001 0010 0011 0100 0101 1110 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xaoi21     $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0000 0001 0010 0011 1100 1101 1110 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnr2       $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0000 0001 0110 0111 1010 1011 1100 1101') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnr3       $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0000 0001 0110 0111 1010 1011 1110 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xooi21     $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0000 0011 0101 0110 1001 1010 1100 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xnr4       $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0000 0011 0101 0111 1010 1011 1101 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xooi31     $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0001 0010 0011 0100 0101 0110 0111 1000') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xoon31     $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0001 0010 0011 0100 1001 1010 1011 1100') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xoon21     $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0001 0010 0100 0111 1000 1011 1101 1110') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xor4       $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0001 0010 0100 0111 1001 1010 1100 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xor3       $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0001 0010 0101 0110 1001 1010 1101 1110') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xor2       $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0001 0011 0101 0110 1001 1011 1101 1110') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xaon21     $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0001 0011 0101 0111 1001 1011 1101 1110') let "num_func=num_func+1"; printf "%4d" $num_func; echo " xaon31     $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0001 0011 0101 0111 1001 1011 1101 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " bf1        $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0001 0011 0101 0111 1010 1011 1110 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " mxn2       $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          '0011 0101 0110 0111 1011 1101 1110 1111') let "num_func=num_func+1"; printf "%4d" $num_func; echo " cgn2       $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
          *)                                         let "num_func=num_func+1"; printf "%4d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8" ;;
        esac ;;
      *)
        let "num_func=num_func+1"; printf "%7d" $num_func; echo "            $minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8"; let "num_func=num_func+1"; printf "%d" $num_func; echo "            not ($minsop1+$minsop2+$minsop3+$minsop4+$minsop5+$minsop6+$minsop7+$minsop8)" ;;
    esac ;;
esac
}

get_lowest_sop()
{
if   [ "$1" -eq 0 ]
then
  sop_exists=0
elif [ "$1" -ge 1 ]
then
  term_index=1
  for term in 3210 3201 3012 3021 3120 3102 \
              2310 2301 2013 2031 2130 2103 \
              1230 1203 1032 1023 1320 1302 \
              0213 0231 0312 0321 0123 0132
  do
    let "index1=${term:3:1}"; let "index2=${term:2:1}"; let "index3=${term:1:1}"; let "index4=${term:0:1}"
    if   [ "$1" -eq 1 ]
    then
      newsop1=${sop1:$index1:1}${sop1:$index2:1}${sop1:$index3:1}${sop1:$index4:1}
      echo $newsop1 > $$_ordered_sop
      sort $$_ordered_sop -o $$_ordered_sop
      first_sop=$(sed -n '1 p' $$_ordered_sop)
      if   [ "$term_index" -eq 1 ]
      then
        minsop1=$first_sop
        if [ "$[2#$minsop1]" -eq 0 ]; then break; fi
      else
        if [ "$[2#$first_sop]" -lt "$[2#$minsop1]" ]; then minsop1=$first_sop; fi
      fi
    elif [ "$1" -eq 2 ]
    then
      newsop1=${sop1:$index1:1}${sop1:$index2:1}${sop1:$index3:1}${sop1:$index4:1}
      newsop2=${sop2:$index1:1}${sop2:$index2:1}${sop2:$index3:1}${sop2:$index4:1}
      echo $newsop1 > $$_ordered_sop
      echo $newsop2 >> $$_ordered_sop
      sort $$_ordered_sop -o $$_ordered_sop
      first_sop=$(sed -n '1 p' $$_ordered_sop)
      second_sop=$(sed -n '2 p' $$_ordered_sop)
      if [ "$term_index" -eq 1 ]
      then
        minsop1=$first_sop
        minsop2=$second_sop
      else
        if   [ "$[2#$first_sop]" -lt "$[2#$minsop1]" ]
        then
          minsop1=$first_sop
          minsop2=$second_sop
        elif [ "$[2#$first_sop]" -eq "$[2#$minsop1]" ]
        then
          if [ "$[2#$second_sop]" -lt "$[2#$minsop2]" ]; then minsop2=$second_sop; fi
        fi
      fi
    elif [ "$1" -eq 3 ]
    then
      newsop1=${sop1:$index1:1}${sop1:$index2:1}${sop1:$index3:1}${sop1:$index4:1}
      newsop2=${sop2:$index1:1}${sop2:$index2:1}${sop2:$index3:1}${sop2:$index4:1}
      newsop3=${sop3:$index1:1}${sop3:$index2:1}${sop3:$index3:1}${sop3:$index4:1}
      echo $newsop1 > $$_ordered_sop
      echo $newsop2 >> $$_ordered_sop
      echo $newsop3 >> $$_ordered_sop
      sort $$_ordered_sop -o $$_ordered_sop
      first_sop=$(sed -n '1 p' $$_ordered_sop)
      second_sop=$(sed -n '2 p' $$_ordered_sop)
      third_sop=$(sed -n '3 p' $$_ordered_sop)
      if [ "$term_index" -eq 1 ]
      then
        minsop1=$first_sop
        minsop2=$second_sop
        minsop3=$third_sop
      else
        if   [ "$[2#$first_sop]" -lt "$[2#$minsop1]" ]
        then
          minsop1=$first_sop
          minsop2=$second_sop
          minsop3=$third_sop
        elif [ "$[2#$first_sop]" -eq "$[2#$minsop1]" ]
        then
          if   [ "$[2#$second_sop]" -lt "$[2#$minsop2]" ]
          then
            minsop2=$second_sop
            minsop3=$third_sop
          elif [ "$[2#$second_sop]" -eq "$[2#$minsop2]" ]
          then
            if [ "$[2#$third_sop]" -lt "$[2#$minsop3]" ]; then minsop3=$third_sop; fi
          fi
        fi
      fi
    elif [ "$1" -eq 4 ]
    then
      newsop1=${sop1:$index1:1}${sop1:$index2:1}${sop1:$index3:1}${sop1:$index4:1}
      newsop2=${sop2:$index1:1}${sop2:$index2:1}${sop2:$index3:1}${sop2:$index4:1}
      newsop3=${sop3:$index1:1}${sop3:$index2:1}${sop3:$index3:1}${sop3:$index4:1}
      newsop4=${sop4:$index1:1}${sop4:$index2:1}${sop4:$index3:1}${sop4:$index4:1}
      echo $newsop1 > $$_ordered_sop
      echo $newsop2 >> $$_ordered_sop
      echo $newsop3 >> $$_ordered_sop
      echo $newsop4 >> $$_ordered_sop
      sort $$_ordered_sop -o $$_ordered_sop
      first_sop=$(sed -n '1 p' $$_ordered_sop)
      second_sop=$(sed -n '2 p' $$_ordered_sop)
      third_sop=$(sed -n '3 p' $$_ordered_sop)
      fourth_sop=$(sed -n '4 p' $$_ordered_sop)
      if [ "$term_index" -eq 1 ]
      then
        minsop1=$first_sop
        minsop2=$second_sop
        minsop3=$third_sop
        minsop4=$fourth_sop
      else
        if   [ "$[2#$first_sop]" -lt "$[2#$minsop1]" ]
        then
          minsop1=$first_sop
          minsop2=$second_sop
          minsop3=$third_sop
          minsop4=$fourth_sop
        elif [ "$[2#$first_sop]" -eq "$[2#$minsop1]" ]
        then
          if   [ "$[2#$second_sop]" -lt "$[2#$minsop2]" ]
          then
            minsop2=$second_sop
            minsop3=$third_sop
            minsop4=$fourth_sop
          elif [ "$[2#$second_sop]" -eq "$[2#$minsop2]" ]
          then
            if   [ "$[2#$third_sop]" -lt "$[2#$minsop3]" ]
            then
              minsop3=$third_sop
              minsop4=$fourth_sop
            elif [ "$[2#$third_sop]" -eq "$[2#$minsop3]" ]
            then
              if [ "$[2#$fourth_sop]" -lt "$[2#$minsop4]" ]; then minsop4=$fourth_sop; fi
            fi
          fi
        fi
      fi
    elif [ "$1" -eq 5 ]
    then
      newsop1=${sop1:$index1:1}${sop1:$index2:1}${sop1:$index3:1}${sop1:$index4:1}
      newsop2=${sop2:$index1:1}${sop2:$index2:1}${sop2:$index3:1}${sop2:$index4:1}
      newsop3=${sop3:$index1:1}${sop3:$index2:1}${sop3:$index3:1}${sop3:$index4:1}
      newsop4=${sop4:$index1:1}${sop4:$index2:1}${sop4:$index3:1}${sop4:$index4:1}
      newsop5=${sop5:$index1:1}${sop5:$index2:1}${sop5:$index3:1}${sop5:$index4:1}
      echo $newsop1 > $$_ordered_sop
      echo $newsop2 >> $$_ordered_sop
      echo $newsop3 >> $$_ordered_sop
      echo $newsop4 >> $$_ordered_sop
      echo $newsop5 >> $$_ordered_sop
      sort $$_ordered_sop -o $$_ordered_sop
      first_sop=$(sed -n '1 p' $$_ordered_sop)
      second_sop=$(sed -n '2 p' $$_ordered_sop)
      third_sop=$(sed -n '3 p' $$_ordered_sop)
      fourth_sop=$(sed -n '4 p' $$_ordered_sop)
      fifth_sop=$(sed -n '5 p' $$_ordered_sop)
      if [ "$term_index" -eq 1 ]
      then
        minsop1=$first_sop
        minsop2=$second_sop
        minsop3=$third_sop
        minsop4=$fourth_sop
        minsop5=$fifth_sop
      else
        if   [ "$[2#$first_sop]" -lt "$[2#$minsop1]" ]
        then
          minsop1=$first_sop
          minsop2=$second_sop
          minsop3=$third_sop
          minsop4=$fourth_sop
          minsop5=$fifth_sop
        elif [ "$[2#$first_sop]" -eq "$[2#$minsop1]" ]
        then
          if   [ "$[2#$second_sop]" -lt "$[2#$minsop2]" ]
          then
            minsop2=$second_sop
            minsop3=$third_sop
            minsop4=$fourth_sop
            minsop5=$fifth_sop
          elif [ "$[2#$second_sop]" -eq "$[2#$minsop2]" ]
          then
            if   [ "$[2#$third_sop]" -lt "$[2#$minsop3]" ]
            then
              minsop3=$third_sop
              minsop4=$fourth_sop
              minsop5=$fifth_sop
            elif [ "$[2#$third_sop]" -eq "$[2#$minsop3]" ]
            then
              if   [ "$[2#$fourth_sop]" -lt "$[2#$minsop4]" ]
              then
                minsop4=$fourth_sop
                minsop5=$fifth_sop
              elif [ "$[2#$fourth_sop]" -eq "$[2#$minsop4]" ]
              then
                if [ "$[2#$fifth_sop]" -lt "$[2#$minsop5]" ]; then minsop5=$fifth_sop; fi
              fi
            fi
          fi
        fi
      fi
    elif [ "$1" -eq 6 ]
    then
      newsop1=${sop1:$index1:1}${sop1:$index2:1}${sop1:$index3:1}${sop1:$index4:1}
      newsop2=${sop2:$index1:1}${sop2:$index2:1}${sop2:$index3:1}${sop2:$index4:1}
      newsop3=${sop3:$index1:1}${sop3:$index2:1}${sop3:$index3:1}${sop3:$index4:1}
      newsop4=${sop4:$index1:1}${sop4:$index2:1}${sop4:$index3:1}${sop4:$index4:1}
      newsop5=${sop5:$index1:1}${sop5:$index2:1}${sop5:$index3:1}${sop5:$index4:1}
      newsop6=${sop6:$index1:1}${sop6:$index2:1}${sop6:$index3:1}${sop6:$index4:1}
      echo $newsop1 > $$_ordered_sop
      echo $newsop2 >> $$_ordered_sop
      echo $newsop3 >> $$_ordered_sop
      echo $newsop4 >> $$_ordered_sop
      echo $newsop5 >> $$_ordered_sop
      echo $newsop6 >> $$_ordered_sop
      sort $$_ordered_sop -o $$_ordered_sop
      first_sop=$(sed -n '1 p' $$_ordered_sop)
      second_sop=$(sed -n '2 p' $$_ordered_sop)
      third_sop=$(sed -n '3 p' $$_ordered_sop)
      fourth_sop=$(sed -n '4 p' $$_ordered_sop)
      fifth_sop=$(sed -n '5 p' $$_ordered_sop)
      sixth_sop=$(sed -n '6 p' $$_ordered_sop)
      if [ "$term_index" -eq 1 ]
      then
        minsop1=$first_sop
        minsop2=$second_sop
        minsop3=$third_sop
        minsop4=$fourth_sop
        minsop5=$fifth_sop
        minsop6=$sixth_sop
      else
        if   [ "$[2#$first_sop]" -lt "$[2#$minsop1]" ]
        then
          minsop1=$first_sop
          minsop2=$second_sop
          minsop3=$third_sop
          minsop4=$fourth_sop
          minsop5=$fifth_sop
          minsop6=$sixth_sop
        elif [ "$[2#$first_sop]" -eq "$[2#$minsop1]" ]
        then
          if   [ "$[2#$second_sop]" -lt "$[2#$minsop2]" ]
          then
            minsop2=$second_sop
            minsop3=$third_sop
            minsop4=$fourth_sop
            minsop5=$fifth_sop
            minsop6=$sixth_sop
          elif [ "$[2#$second_sop]" -eq "$[2#$minsop2]" ]
          then
            if   [ "$[2#$third_sop]" -lt "$[2#$minsop3]" ]
            then
              minsop3=$third_sop
              minsop4=$fourth_sop
              minsop5=$fifth_sop
              minsop6=$sixth_sop
            elif [ "$[2#$third_sop]" -eq "$[2#$minsop3]" ]
            then
              if   [ "$[2#$fourth_sop]" -lt "$[2#$minsop4]" ]
              then
                minsop4=$fourth_sop
                minsop5=$fifth_sop
                minsop6=$sixth_sop
              elif [ "$[2#$fourth_sop]" -eq "$[2#$minsop4]" ]
              then
                if   [ "$[2#$fifth_sop]" -lt "$[2#$minsop5]" ]
                then
                  minsop5=$fifth_sop
                  minsop6=$sixth_sop
                elif [ "$[2#$fifth_sop]" -eq "$[2#$minsop5]" ]
                then
                  if [ "$[2#$sixth_sop]" -lt "$[2#$minsop6]" ]; then minsop6=$sixth_sop; fi
                fi
              fi
            fi
          fi
        fi
      fi
    elif [ "$1" -eq 7 ]
    then
      newsop1=${sop1:$index1:1}${sop1:$index2:1}${sop1:$index3:1}${sop1:$index4:1}
      newsop2=${sop2:$index1:1}${sop2:$index2:1}${sop2:$index3:1}${sop2:$index4:1}
      newsop3=${sop3:$index1:1}${sop3:$index2:1}${sop3:$index3:1}${sop3:$index4:1}
      newsop4=${sop4:$index1:1}${sop4:$index2:1}${sop4:$index3:1}${sop4:$index4:1}
      newsop5=${sop5:$index1:1}${sop5:$index2:1}${sop5:$index3:1}${sop5:$index4:1}
      newsop6=${sop6:$index1:1}${sop6:$index2:1}${sop6:$index3:1}${sop6:$index4:1}
      newsop7=${sop7:$index1:1}${sop7:$index2:1}${sop7:$index3:1}${sop7:$index4:1}
      echo $newsop1 > $$_ordered_sop
      echo $newsop2 >> $$_ordered_sop
      echo $newsop3 >> $$_ordered_sop
      echo $newsop4 >> $$_ordered_sop
      echo $newsop5 >> $$_ordered_sop
      echo $newsop6 >> $$_ordered_sop
      echo $newsop7 >> $$_ordered_sop
      sort $$_ordered_sop -o $$_ordered_sop
      first_sop=$(sed -n '1 p' $$_ordered_sop)
      second_sop=$(sed -n '2 p' $$_ordered_sop)
      third_sop=$(sed -n '3 p' $$_ordered_sop)
      fourth_sop=$(sed -n '4 p' $$_ordered_sop)
      fifth_sop=$(sed -n '5 p' $$_ordered_sop)
      sixth_sop=$(sed -n '6 p' $$_ordered_sop)
      seventh_sop=$(sed -n '7 p' $$_ordered_sop)
      if [ "$term_index" -eq 1 ]
      then
        minsop1=$first_sop
        minsop2=$second_sop
        minsop3=$third_sop
        minsop4=$fourth_sop
        minsop5=$fifth_sop
        minsop6=$sixth_sop
        minsop7=$seventh_sop
      else
        if   [ "$[2#$first_sop]" -lt "$[2#$minsop1]" ]
        then
          minsop1=$first_sop
          minsop2=$second_sop
          minsop3=$third_sop
          minsop4=$fourth_sop
          minsop5=$fifth_sop
          minsop6=$sixth_sop
          minsop7=$seventh_sop
        elif [ "$[2#$first_sop]" -eq "$[2#$minsop1]" ]
        then
          if   [ "$[2#$second_sop]" -lt "$[2#$minsop2]" ]
          then
            minsop2=$second_sop
            minsop3=$third_sop
            minsop4=$fourth_sop
            minsop5=$fifth_sop
            minsop6=$sixth_sop
            minsop7=$seventh_sop
          elif [ "$[2#$second_sop]" -eq "$[2#$minsop2]" ]
          then
            if   [ "$[2#$third_sop]" -lt "$[2#$minsop3]" ]
            then
              minsop3=$third_sop
              minsop4=$fourth_sop
              minsop5=$fifth_sop
              minsop6=$sixth_sop
              minsop7=$seventh_sop
            elif [ "$[2#$third_sop]" -eq "$[2#$minsop3]" ]
            then
              if   [ "$[2#$fourth_sop]" -lt "$[2#$minsop4]" ]
              then
                minsop4=$fourth_sop
                minsop5=$fifth_sop
                minsop6=$sixth_sop
                minsop7=$seventh_sop
              elif [ "$[2#$fourth_sop]" -eq "$[2#$minsop4]" ]
              then
                if   [ "$[2#$fifth_sop]" -lt "$[2#$minsop5]" ]
                then
                  minsop5=$fifth_sop
                  minsop6=$sixth_sop
                  minsop7=$seventh_sop
                elif [ "$[2#$fifth_sop]" -eq "$[2#$minsop5]" ]
                then
                  if   [ "$[2#$sixth_sop]" -lt "$[2#$minsop6]" ]
                  then
                    minsop6=$sixth_sop
                    minsop7=$seventh_sop
                  elif [ "$[2#$sixth_sop]" -eq "$[2#$minsop6]" ]
                  then
                    if [ "$[2#$seventh_sop]" -lt "$[2#$minsop7]" ]; then minsop7=$seventh_sop; fi
                  fi
                fi
              fi
            fi
          fi
        fi
      fi
    elif [ "$1" -eq 8 ]
    then
      newsop1=${sop1:$index1:1}${sop1:$index2:1}${sop1:$index3:1}${sop1:$index4:1}
      newsop2=${sop2:$index1:1}${sop2:$index2:1}${sop2:$index3:1}${sop2:$index4:1}
      newsop3=${sop3:$index1:1}${sop3:$index2:1}${sop3:$index3:1}${sop3:$index4:1}
      newsop4=${sop4:$index1:1}${sop4:$index2:1}${sop4:$index3:1}${sop4:$index4:1}
      newsop5=${sop5:$index1:1}${sop5:$index2:1}${sop5:$index3:1}${sop5:$index4:1}
      newsop6=${sop6:$index1:1}${sop6:$index2:1}${sop6:$index3:1}${sop6:$index4:1}
      newsop7=${sop7:$index1:1}${sop7:$index2:1}${sop7:$index3:1}${sop7:$index4:1}
      newsop8=${sop8:$index1:1}${sop8:$index2:1}${sop8:$index3:1}${sop8:$index4:1}
      echo $newsop1 > $$_ordered_sop
      echo $newsop2 >> $$_ordered_sop
      echo $newsop3 >> $$_ordered_sop
      echo $newsop4 >> $$_ordered_sop
      echo $newsop5 >> $$_ordered_sop
      echo $newsop6 >> $$_ordered_sop
      echo $newsop7 >> $$_ordered_sop
      echo $newsop8 >> $$_ordered_sop
      sort $$_ordered_sop -o $$_ordered_sop
      first_sop=$(sed -n '1 p' $$_ordered_sop)
      second_sop=$(sed -n '2 p' $$_ordered_sop)
      third_sop=$(sed -n '3 p' $$_ordered_sop)
      fourth_sop=$(sed -n '4 p' $$_ordered_sop)
      fifth_sop=$(sed -n '5 p' $$_ordered_sop)
      sixth_sop=$(sed -n '6 p' $$_ordered_sop)
      seventh_sop=$(sed -n '7 p' $$_ordered_sop)
      eigth_sop=$(sed -n '8 p' $$_ordered_sop)
      if [ "$term_index" -eq 1 ]
      then
        minsop1=$first_sop
        minsop2=$second_sop
        minsop3=$third_sop
        minsop4=$fourth_sop
        minsop5=$fifth_sop
        minsop6=$sixth_sop
        minsop7=$seventh_sop
        minsop8=$eigth_sop
      else
        if   [ "$[2#$first_sop]" -lt "$[2#$minsop1]" ]
        then
          minsop1=$first_sop
          minsop2=$second_sop
          minsop3=$third_sop
          minsop4=$fourth_sop
          minsop5=$fifth_sop
          minsop6=$sixth_sop
          minsop7=$seventh_sop
          minsop8=$eigth_sop
        elif [ "$[2#$first_sop]" -eq "$[2#$minsop1]" ]
        then
          if   [ "$[2#$second_sop]" -lt "$[2#$minsop2]" ]
          then
            minsop2=$second_sop
            minsop3=$third_sop
            minsop4=$fourth_sop
            minsop5=$fifth_sop
            minsop6=$sixth_sop
            minsop7=$seventh_sop
            minsop8=$eigth_sop
          elif [ "$[2#$second_sop]" -eq "$[2#$minsop2]" ]
          then
            if   [ "$[2#$third_sop]" -lt "$[2#$minsop3]" ]
            then
              minsop3=$third_sop
              minsop4=$fourth_sop
              minsop5=$fifth_sop
              minsop6=$sixth_sop
              minsop7=$seventh_sop
              minsop8=$eigth_sop
            elif [ "$[2#$third_sop]" -eq "$[2#$minsop3]" ]
            then
              if   [ "$[2#$fourth_sop]" -lt "$[2#$minsop4]" ]
              then
                minsop4=$fourth_sop
                minsop5=$fifth_sop
                minsop6=$sixth_sop
                minsop7=$seventh_sop
                minsop8=$eigth_sop
              elif [ "$[2#$fourth_sop]" -eq "$[2#$minsop4]" ]
              then
                if   [ "$[2#$fifth_sop]" -lt "$[2#$minsop5]" ]
                then
                  minsop5=$fifth_sop
                  minsop6=$sixth_sop
                  minsop7=$seventh_sop
                  minsop8=$eigth_sop
                elif [ "$[2#$fifth_sop]" -eq "$[2#$minsop5]" ]
                then
                  if   [ "$[2#$sixth_sop]" -lt "$[2#$minsop6]" ]
                  then
                    minsop6=$sixth_sop
                    minsop7=$seventh_sop
                    minsop8=$eigth_sop
                  elif [ "$[2#$sixth_sop]" -eq "$[2#$minsop6]" ]
                  then
                    if [ "$[2#$seventh_sop]" -lt "$[2#$minsop7]" ]
                    then
                      minsop7=$seventh_sop
                      minsop8=$eigth_sop
                    elif [ "$[2#$seventh_sop]" -eq "$[2#$minsop7]" ]
                    then
                      if [ "$[2#$eigth_sop]" -lt "$[2#$minsop8]" ]; then minsop8=$eigth_sop; fi
                    fi
                  fi
                fi
              fi
            fi
          fi
        fi
      fi
    fi
    let "term_index+=1"
  done
  case $1 in
    1) sop_exists=$(grep -c "^$minsop1$" $$_sop_list)
       if [ "$sop_exists" -eq 0 ]; then echo $minsop1 >> $$_sop_list; fi ;;
    2) sop_exists=$(grep -c "^$minsop1 $minsop2$" $$_sop_list)
       if [ "$sop_exists" -eq 0 ]; then echo $minsop1' '$minsop2 >> $$_sop_list; fi ;;
    3) sop_exists=$(grep -c "^$minsop1 $minsop2 $minsop3$" $$_sop_list)
       if [ "$sop_exists" -eq 0 ]; then echo $minsop1' '$minsop2' '$minsop3 >> $$_sop_list; fi ;;
    4) sop_exists=$(grep -c "^$minsop1 $minsop2 $minsop3 $minsop4$" $$_sop_list)
       if [ "$sop_exists" -eq 0 ]; then echo $minsop1' '$minsop2' '$minsop3' '$minsop4 >> $$_sop_list; fi ;;
    5) sop_exists=$(grep -c "^$minsop1 $minsop2 $minsop3 $minsop4 $minsop5$" $$_sop_list)
       if [ "$sop_exists" -eq 0 ]; then echo $minsop1' '$minsop2' '$minsop3' '$minsop4' '$minsop5 >> $$_sop_list; fi ;;
    6) sop_exists=$(grep -c "^$minsop1 $minsop2 $minsop3 $minsop4 $minsop5 $minsop6$" $$_sop_list)
       if [ "$sop_exists" -eq 0 ]; then echo $minsop1' '$minsop2' '$minsop3' '$minsop4' '$minsop5' '$minsop6 >> $$_sop_list; fi ;;
    7) sop_exists=$(grep -c "^$minsop1 $minsop2 $minsop3 $minsop4 $minsop5 $minsop6 $minsop7$" $$_sop_list)
       if [ "$sop_exists" -eq 0 ]; then echo $minsop1' '$minsop2' '$minsop3' '$minsop4' '$minsop5' '$minsop6' '$minsop7 >> $$_sop_list; fi ;;
    8) sop_exists=$(grep -c "^$minsop1 $minsop2 $minsop3 $minsop4 $minsop5 $minsop6 $minsop7 $minsop8$" $$_sop_list)
       if [ "$sop_exists" -eq 0 ]; then echo $minsop1' '$minsop2' '$minsop3' '$minsop4' '$minsop5' '$minsop6' '$minsop7' '$minsop8 >> $$_sop_list; fi ;;
  esac
fi
}

output_sops()
{
get_lowest_sop $1
if [ "$sop_exists" -eq 0 ]
then
  print_sops $1
fi
}

#######################
# Execution begins here.

for num_inputs in $req_inputs
do
  case $num_inputs in
  1) num_sop_terms='0 1' ;;
  2) num_sop_terms='0 1 2' ;;
  3) num_sop_terms='0 1 2 3 4' ;;
  4) num_sop_terms='0 1 2 3 4 5 6 7 8' ;;
  esac
done

for num_sop_term in $num_sop_terms
do
  rm -f $$_sop_list; touch $$_sop_list
  if [ "$num_sop_term" -eq 0 ]
  then
    output_sops 0
    continue
  fi
  for sop1 in 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
  do
    if [ "$num_sop_term" -eq 1 ]
    then
      if   [ "$num_inputs" -eq 1 -a "$[2#$sop1]" -eq 2 ]; then break
      elif [ "$num_inputs" -eq 2 -a "$[2#$sop1]" -eq 4 ]; then break
      elif [ "$num_inputs" -eq 3 -a "$[2#$sop1]" -eq 8 ]; then break
      elif [ "$num_inputs" -eq 4 -a "$[2#$sop1]" -eq 16 ]; then break
      else
        output_sops 1 $sop1
        continue
      fi
    fi
    for sop2 in 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
    do
      if [ "$sop2" -le "$sop1" ]
      then
        continue
      fi
      if   [ "$num_inputs" -eq 2 -a "$[2#$sop2]" -eq 4 ]; then
        if [ "$[2#$sop1]" -eq 3 ]; then break 2; else break; fi
      elif [ "$num_inputs" -eq 3 -a "$[2#$sop2]" -eq 8 ]; then
        if [ "$[2#$sop1]" -eq 7 ]; then break 2; else break; fi
      elif [ "$num_inputs" -eq 4 -a "$[2#$sop2]" -eq 16 ]; then
        if [ "$[2#$sop1]" -eq 15 ]; then break 2; else break; fi
      fi
      if [ "$num_sop_term" -eq 2 ]
      then
        output_sops 2 ${sop1}_${sop2}
        continue
      fi
      for sop3 in 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
      do
        if [ "$sop3" -le "$sop2" -o "$sop3" -eq "$sop1" ]
        then
          continue
        fi
        if   [ "$num_inputs" -eq 3 -a "$[2#$sop3]" -eq 8 ]; then
          if [ "$[2#$sop2]" -eq 7 ]; then break 2; else break; fi
        elif [ "$num_inputs" -eq 4 -a "$[2#$sop3]" -eq 16 ]; then
          if [ "$[2#$sop2]" -eq 15 ]; then break 2; else break; fi
        fi
        if [ "$num_sop_term" -eq 3 ]
        then
          output_sops 3 ${sop1}_${sop2}_${sop3}
          continue
        fi
        for sop4 in 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
        do
          if [ "$sop4" -le "$sop3" -o "$sop4" -eq "$sop1" -o "$sop4" -eq "$sop2" ]
          then
            continue
          fi
          if   [ "$num_inputs" -eq 3 -a "$[2#$sop4]" -eq 8 ]; then
            if [ "$[2#$sop3]" -eq 7 ]; then break 2; else break; fi
          elif [ "$num_inputs" -eq 4 -a "$[2#$sop4]" -eq 16 ]; then
            if [ "$[2#$sop3]" -eq 15 ]; then break 2; else break; fi
          fi
          if [ "$num_sop_term" -eq 4 ]
          then
            output_sops 4 ${sop1}_${sop2}_${sop3}_${sop4}
            continue
          fi
          for sop5 in 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
          do
            if [ "$sop5" -le "$sop4" -o "$sop5" -eq "$sop1" -o "$sop5" -eq "$sop2" -o "$sop5" -eq "$sop3" ]
            then
              continue
            fi
            if [ "$num_sop_term" -eq 5 ]
            then
              output_sops 5 ${sop1}_${sop2}_${sop3}_${sop4}_${sop5}
              continue
            fi
            for sop6 in 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
            do
              if [ "$sop6" -le "$sop5" -o "$sop6" -eq "$sop1" -o "$sop6" -eq "$sop2" -o "$sop6" -eq "$sop3" -o "$sop6" -eq "$sop4" ]
              then
                continue
              fi
              if [ "$num_sop_term" -eq 6 ]
              then
                output_sops 6 ${sop1}_${sop2}_${sop3}_${sop4}_${sop5}_${sop6}
                continue
              fi
              for sop7 in 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
              do
                if [ "$sop7" -le "$sop6" -o "$sop7" -eq "$sop1" -o "$sop7" -eq "$sop2" -o "$sop7" -eq "$sop3" -o "$sop7" -eq "$sop4" -o "$sop7" -eq "$sop5" ]
                then
                  continue
                fi
                if [ "$num_sop_term" -eq 7 ]
                then
                  output_sops 7 ${sop1}_${sop2}_${sop3}_${sop4}_${sop5}_${sop6}_${sop7}
                  continue
                fi
                for sop8 in 0111 1000 1001 1010 1011 1100 1101 1110 1111
                do
                  if [ "$sop8" -le "$sop7" -o "$sop8" -eq "$sop1" -o "$sop8" -eq "$sop2" -o "$sop8" -eq "$sop3" -o "$sop8" -eq "$sop4" -o "$sop8" -eq "$sop5" -o "$sop8" -eq "$sop6" ]
                  then
                    continue
                  fi
                  if [ "$num_sop_term" -eq 8 ]
                  then
                    output_sops 8 ${sop1}_${sop2}_${sop3}_${sop4}_${sop5}_${sop6}_${sop7}_${sop8}
                    continue
                  fi
                done
              done
            done
          done
        done
      done
    done
  done
done
rm $$_ordered_sop $$_sop_list
echo "# Total "$num_func" functions with "$num_inputs" inputs" 1>&2

