<commit_before>//  Copyright (c) 2014 <NAME>. All rights reserved.

import Set

/// A (potentially ambiguous, but otherwise binary) parse tree.
enum ParseTree<T : Hashable> {
	/// Represents the termination of a branch (list).
	case Nil
	
	/// Represents a leaf node.
	case Leaf(Box<T>)
	
	/// Represents a binary branch node.
	///
	/// S-list–style constructions use this, coupled with .Leaf() and .Nil.
	case Branch(Box<ParseTree<T>>, Box<ParseTree<T>>)
	
	/// Represents an ambiguity in the parse tree.
	case Choice(Set<ParseTree<T>>)
	
	init() {
		self = .Nil
	}
	
	init(leaf: T) {
		self = .Leaf(box(leaf))
	}
	
	init(left: ParseTree<T>, right: ParseTree<T>) {
		self = .Branch(box(left), box(right))
	}
	
	init<S : Sequence where S.GeneratorType.Element == ParseTree<T>>(trees: S) {
		let set: Set<ParseTree<T>> = Set(trees)
		switch set.count {
		case 0:
			self = .Nil
		case 1:
			self = set[]
		default:
			self = .Choice(set)
		}
	}
}


/// ParseTree conforms to Equatable.
func == <T> (a: ParseTree<T>, b: ParseTree<T>) -> Bool {
	switch (a, b) {
	case (.Nil, .Nil):
		return true
		
	case let (.Leaf(x), .Leaf(y)) where x == y:
		return true
		
	case let (.Branch(x1, y1), .Branch(x2, y2)) where x1.value == x2.value && y1.value == y2.value:
		return true
		
	case let (.Choice(x), .Choice(y)) where x == y:
		return true
		
	default:
		return false
	}
}


/// ParseTree conforms to Hashable.
extension ParseTree : Hashable {
	var hashValue: Int {
		switch self {
		case .Nil:
			return 0
			
		case let .Leaf(x):
			return x.value.hashValue
			
		case let .Branch(x, y):
			return x.value.hashValue ^ y.value.hashValue
			
		case let .Choice(x):
			return x.hashValue
		}
	}
}


/// ParseTree conforms to Printable.
extension ParseTree : Printable {
	var description: String {
		switch self {
		case .Nil:
			return "()"
		
		case let .Leaf(x):
			return toString(x.value)
			
		case let .Branch(x, y):
			return "(\(x.value.description) . \(y.value.description))"
			
		case let .Choice(x):
			return x.description
		}
	}
}


func +<T> (a: ParseTree<T>, b: ParseTree<T>) -> ParseTree<T> {
	switch (a, b) {
	case let (x, .Nil):
		return x
	case let (.Nil, y):
		return y
	
	case let (.Choice(x), .Choice(y)):
		return ParseTree(trees: x + y)<commit_msg>Style.<commit_after>//  Copyright (c) 2014 <NAME>. All rights reserved.

import Set

/// A (potentially ambiguous, but otherwise binary) parse tree.
enum ParseTree<T : Hashable> {
	/// Represents the termination of a branch (list).
	case Nil
	
	/// Represents a leaf node.
	case Leaf(Box<T>)
	
	/// Represents a binary branch node.
	///
	/// S-list–style constructions use this, coupled with .Leaf() and .Nil.
	case Branch(Box<ParseTree<T>>, Box<ParseTree<T>>)
	
	/// Represents an ambiguity in the parse tree.
	case Choice(Set<ParseTree<T>>)
	
	init() {
		self = .Nil
	}
	
	init(leaf: T) {
		self = .Leaf(box(leaf))
	}
	
	init(left: ParseTree<T>, right: ParseTree<T>) {
		self = .Branch(box(left), box(right))
	}
	
	init<S : Sequence where S.GeneratorType.Element == ParseTree<T>>(trees: S) {
		let set: Set<ParseTree<T>> = Set(trees)
		switch set.count {
		case 0:
			self = .Nil
		case 1:
			self = set[]
		default:
			self = .Choice(set)
		}
	}
}


/// ParseTree conforms to Equatable.
func == <T> (a: ParseTree<T>, b: ParseTree<T>) -> Bool {
	switch (a, b) {
	case (.Nil, .Nil):
		return true
		
	case let (.Leaf(x), .Leaf(y)) where x == y:
		return true
		
	case let (.Branch(x1, y1), .Branch(x2, y2)) where x1.value == x2.value && y1.value == y2.value:
		return true
		
	case let (.Choice(x), .Choice(y)) where x == y:
		return true
		
	default:
		return false
	}
}


/// ParseTree conforms to Hashable.
extension ParseTree : Hashable {
	var hashValue: Int {
		switch self {
		case .Nil:
			return 0
			
		case let .Leaf(x):
			return x.value.hashValue
			
		case let .Branch(x, y):
			return x.value.hashValue ^ y.value.hashValue
			
		case let .Choice(x):
			return x.hashValue
		}
	}
}


/// ParseTree conforms to Printable.
extension ParseTree : Printable {
	var description: String {
		switch self {
		case .Nil:
			return "()"
		
		case let .Leaf(x):
			return toString(x.value)
			
		case let .Branch(x, y):
			return "(\(x.value.description) . \(y.value.description))"
			
		case let .Choice(x):
			return x.description
		}
	}
}


func + <T> (a: ParseTree<T>, b: ParseTree<T>) -> ParseTree<T> {
	switch (a, b) {
	case let (x, .Nil):
		return x
	case let (.Nil, y):
		return y
	
	case let (.Choice(x), .Choice(y)):
		return ParseTree(trees: x + y)
{'fraction_non_alphanumeric': 0.15878975265017667, 'fraction_numerical': 0.0066254416961130744, 'mean_word_length': 2.8155012636899746, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2060352', 'n_tokens_mistral': 1905, 'n_tokens_neox': 1671, 'n_words': 493}