...
  
  
     1  
     2  
     3  
     4  
     5  package types2
     6  
     7  import "strings"
     8  
     9  
    10  
    11  
    12  
    13  
    14  type termlist []*term
    15  
    16  
    17  
    18  var allTermlist = termlist{new(term)}
    19  
    20  
    21  const termSep = " | "
    22  
    23  
    24  func (xl termlist) String() string {
    25  	if len(xl) == 0 {
    26  		return "∅"
    27  	}
    28  	var buf strings.Builder
    29  	for i, x := range xl {
    30  		if i > 0 {
    31  			buf.WriteString(termSep)
    32  		}
    33  		buf.WriteString(x.String())
    34  	}
    35  	return buf.String()
    36  }
    37  
    38  
    39  func (xl termlist) isEmpty() bool {
    40  	
    41  	
    42  	
    43  	for _, x := range xl {
    44  		if x != nil {
    45  			return false
    46  		}
    47  	}
    48  	return true
    49  }
    50  
    51  
    52  func (xl termlist) isAll() bool {
    53  	
    54  	
    55  	
    56  	for _, x := range xl {
    57  		if x != nil && x.typ == nil {
    58  			return true
    59  		}
    60  	}
    61  	return false
    62  }
    63  
    64  
    65  func (xl termlist) norm() termlist {
    66  	
    67  	
    68  	used := make([]bool, len(xl))
    69  	var rl termlist
    70  	for i, xi := range xl {
    71  		if xi == nil || used[i] {
    72  			continue
    73  		}
    74  		for j := i + 1; j < len(xl); j++ {
    75  			xj := xl[j]
    76  			if xj == nil || used[j] {
    77  				continue
    78  			}
    79  			if u1, u2 := xi.union(xj); u2 == nil {
    80  				
    81  				
    82  				
    83  				
    84  				
    85  				
    86  				if u1.typ == nil {
    87  					return allTermlist
    88  				}
    89  				xi = u1
    90  				used[j] = true 
    91  			}
    92  		}
    93  		rl = append(rl, xi)
    94  	}
    95  	return rl
    96  }
    97  
    98  
    99  func (xl termlist) union(yl termlist) termlist {
   100  	return append(xl, yl...).norm()
   101  }
   102  
   103  
   104  func (xl termlist) intersect(yl termlist) termlist {
   105  	if xl.isEmpty() || yl.isEmpty() {
   106  		return nil
   107  	}
   108  
   109  	
   110  	
   111  	var rl termlist
   112  	for _, x := range xl {
   113  		for _, y := range yl {
   114  			if r := x.intersect(y); r != nil {
   115  				rl = append(rl, r)
   116  			}
   117  		}
   118  	}
   119  	return rl.norm()
   120  }
   121  
   122  
   123  func (xl termlist) equal(yl termlist) bool {
   124  	
   125  	return xl.subsetOf(yl) && yl.subsetOf(xl)
   126  }
   127  
   128  
   129  func (xl termlist) includes(t Type) bool {
   130  	for _, x := range xl {
   131  		if x.includes(t) {
   132  			return true
   133  		}
   134  	}
   135  	return false
   136  }
   137  
   138  
   139  func (xl termlist) supersetOf(y *term) bool {
   140  	for _, x := range xl {
   141  		if y.subsetOf(x) {
   142  			return true
   143  		}
   144  	}
   145  	return false
   146  }
   147  
   148  
   149  func (xl termlist) subsetOf(yl termlist) bool {
   150  	if yl.isEmpty() {
   151  		return xl.isEmpty()
   152  	}
   153  
   154  	
   155  	for _, x := range xl {
   156  		if !yl.supersetOf(x) {
   157  			return false 
   158  		}
   159  	}
   160  	return true
   161  }
   162  
View as plain text