Set Theory Library
Features
- CustomSet
Standard set implementation with unique elements - MultiSet
Set implementation allowing duplicate elements with multiplicity - Basic Operations
Union, Intersection, Complement, Difference, Symmetric Difference - Advanced Operations
Cartesian Product, Power Set, Partition Validation - Set Laws: Verification methods for all standard set theory laws
- Inclusion-Exclusion Principle
For 2 and 3 sets - Cardinality Utilities
Comprehensive cardinality calculations and verification - Type-Safe
Full generic support for any data type - Well-Tested
Comprehensive unit test coverage
Installation
Add this to your pubspec.yaml:
dependencies:
set_theory: ^1.0.0
Then run:
dart pub get
Quick Start
import 'package:set_theory/set_theory.dart';
import 'package:set_theory/utils/cardinality.dart';
void main() {
// Create sets
final a = CustomSet<int>([1, 2, 3, 4]);
final b = CustomSet<int>([3, 4, 5, 6]);
// Basic operations
final union = SetOperations.union(a, b);
final intersection = SetOperations.intersection(a, b);
final difference = SetOperations.difference(a, b);
print('A = $a'); // Output: {1, 2, 3, 4}
print('B = $b'); // Output: {3, 4, 5, 6}
print('A ∪ B = $union'); // Output: {1, 2, 3, 4, 5, 6}
print('A ∩ B = $intersection'); // Output: {3, 4}
print('A - B = $difference'); // Output: {1, 2}
// Cardinality calculations
print('|A| = ${CardinalityUtils.cardinality(a)}'); // Output: 4
print('|A ∪ B| = ${CardinalityUtils.unionCardinality(a, b)}'); // Output: 6
}
Usage Guide
Creating Sets
// Empty set
final empty = CustomSet<int>.empty();
// Set with elements
final numbers = CustomSet<int>([1, 2, 3, 4, 5]);
// Set from predicate
final universe = CustomSet<int>(List.generate(100, (i) => i + 1));
final evenNumbers = CustomSet.fromPredicate(
universe.elements,
(x) => x % 2 == 0,
);
// Universal set
final universal = CustomSet.universal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
Set Operations
final a = CustomSet<int>([1, 2, 3, 4, 5]);
final b = CustomSet<int>([4, 5, 6, 7, 8]);
final universal = CustomSet<int>(List.generate(10, (i) => i + 1));
// Intersection (A ∩ B)
final intersection = SetOperations.intersection(a, b);
print('A ∩ B = $intersection'); // Output: {4, 5}
// Union (A ∪ B)
final union = SetOperations.union(a, b);
print('A ∪ B = $union'); // Output: {1, 2, 3, 4, 5, 6, 7, 8}
// Complement (A')
final complement = SetOperations.complement(a, universal);
print("A' = $complement"); // Output: {6, 7, 8, 9, 10}
// Difference (A - B)
final difference = SetOperations.difference(a, b);
print('A - B = $difference'); // Output: {1, 2, 3}
// Symmetric Difference (A ⊕ B)
final symmetricDiff = SetOperations.symmetricDifference(a, b);
print('A ⊕ B = $symmetricDiff'); // Output: {1, 2, 3, 6, 7, 8}
Subset Operations
final a = CustomSet<int>([1, 2, 3]);
final b = CustomSet<int>([1, 2, 3, 4, 5]);
final c = CustomSet<int>([1, 2, 3]);
// Subset (A ⊆ B)
print(a.isSubsetOf(b)); // Output: true
print(a.isSubsetOf(c)); // Output: true
// Proper Subset (A ⊂ B)
print(a.isProperSubsetOf(b)); // Output: true
print(a.isProperSubsetOf(c)); // Output: false (equal sets)
// Superset (A ⊇ B)
print(b.isSupersetOf(a)); // Output: true
// Equality (A = B)
print(a.equals(c)); // Output: true
// Equivalence (|A| = |B|)
print(a.isEquivalentTo(b)); // Output: false
Cardinality Operations
import 'package:set_theory/utils/cardinality.dart';
final a = CustomSet<int>([1, 2, 3, 4, 5]);
final b = CustomSet<int>([4, 5, 6, 7, 8]);
final universal = CustomSet<int>(List.generate(10, (i) => i + 1));
// Basic Cardinality
print('|A| = ${CardinalityUtils.cardinality(a)}'); // Output: 5
print('|B| = ${CardinalityUtils.cardinality(b)}'); // Output: 5
// Union Cardinality (Inclusion-Exclusion)
print('|A ∪ B| = ${CardinalityUtils.unionCardinality(a, b)}'); // Output: 8
// Three Sets Union Cardinality
final c = CustomSet<int>([6, 7, 8, 9, 10]);
print('|A ∪ B ∪ C| = ${CardinalityUtils.unionCardinality3(a, b, c)}');
// Symmetric Difference Cardinality
print('|A ⊕ B| = ${CardinalityUtils.symmetricDifferenceCardinality(a, b)}');
// Difference Cardinality
print('|A - B| = ${CardinalityUtils.differenceCardinality(a, b)}');
// Complement Cardinality
print("|A'| = ${CardinalityUtils.complementCardinality(a, universal)}");
// Cartesian Product Cardinality
final x = CustomSet<int>([1, 2, 3]);
final y = CustomSet<String>(['a', 'b']);
print('|X × Y| = ${CardinalityUtils.cartesianProductCardinality(x, y)}'); // Output: 6
// Power Set Cardinality
final small = CustomSet<int>([1, 2, 3]);
print('|P(A)| = ${CardinalityUtils.powerSetCardinality(small)}'); // Output: 8
// Verify Inclusion-Exclusion Principle
print('Verified: ${CardinalityUtils.verifyInclusionExclusion2(a, b)}');
// Check Set Types
print('Is Empty: ${CardinalityUtils.isEmpty(empty)}');
print('Is Singleton: ${CardinalityUtils.isSingleton(CustomSet<int>([5]))}');
print('Is Finite: ${CardinalityUtils.isFinite(a)}');
// Relationship Queries
print('Exactly One: ${CardinalityUtils.exactlyOne(a, b)}');
print('Both: ${CardinalityUtils.both(a, b)}');
print('At Least One: ${CardinalityUtils.atLeastOne(a, b)}');
print('Neither: ${CardinalityUtils.neither(a, b, universal)}');
// Summary Report
final summary = CardinalityUtils.summary(a, b);
print('Summary: $summary');
// Detailed Report
CardinalityUtils.printReport(a, b, title: 'Set Analysis Report');
Advanced Operations
// Cartesian Product (A × B)
final x = CustomSet<int>([1, 2]);
final y = CustomSet<String>(['a', 'b']);
final cartesian = AdvancedSetOperations.cartesianProduct(x, y);
print('X × Y = $cartesian');
// Output: {(1, a), (1, b), (2, a), (2, b)}
// Power Set (P(A))
final small = CustomSet<int>([1, 2]);
final powerSet = small.powerSet;
print('P({1, 2}) = $powerSet');
// Output: {∅, {1}, {2}, {1, 2}}
print('|P({1, 2})| = ${powerSet.cardinality}'); // Output: 4
// Partition Validation
final original = CustomSet<int>([1, 2, 3, 4, 5, 6, 7, 8]);
final partitions = CustomSet<CustomSet<int>>([
CustomSet([1]),
CustomSet([2, 3, 4]),
CustomSet([5, 6]),
CustomSet([7, 8]),
]);
print(AdvancedSetOperations.isPartition(partitions, original));
// Output: true
Set Laws Verification
final a = CustomSet<int>([1, 2, 3]);
final b = CustomSet<int>([3, 4, 5]);
final universal = CustomSet<int>([1, 2, 3, 4, 5, 6, 7, 8, 9]);
// Verify Commutative Law
print(SetLaws.commutativeUnion(a, b)); // Output: true
print(SetLaws.commutativeIntersection(a, b)); // Output: true
// Verify Distributive Law
final c = CustomSet<int>([5, 6, 7]);
print(SetLaws.distributiveUnion(a, b, c)); // Output: true
print(SetLaws.distributiveIntersection(a, b, c)); // Output: true
// Verify De Morgan's Law
print(SetLaws.deMorganUnion(a, b, universal)); // Output: true
print(SetLaws.deMorganIntersection(a, b, universal)); // Output: true
// Verify Identity Laws
print(SetLaws.identityUnion(a)); // Output: true
print(SetLaws.identityIntersection(a, universal)); // Output: true
Inclusion-Exclusion Principle
// Two sets
final universal = CustomSet<int>(List.generate(100, (i) => i + 1));
final div3 = CustomSet.fromPredicate(
universal.elements,
(x) => x % 3 == 0,
);
final div5 = CustomSet.fromPredicate(
universal.elements,
(x) => x % 5 == 0,
);
final count = AdvancedSetOperations.inclusionExclusion2(div3, div5);
print('Numbers 1-100 divisible by 3 or 5: $count');
// Output: 47
// Three sets
final div7 = CustomSet.fromPredicate(
universal.elements,
(x) => x % 7 == 0,
);
final count3 = AdvancedSetOperations.inclusionExclusion3(div3, div5, div7);
print('Numbers 1-100 divisible by 3, 5, or 7: $count3');
// Using CardinalityUtils
final countAlt = CardinalityUtils.unionCardinality(div3, div5);
print('Alternative calculation: $countAlt'); // Output: 47
Multiset Operations
// Create multisets
final p = MultiSet<String>.fromIterable(['a', 'a', 'a', 'c', 'd', 'd']);
final q = MultiSet<String>.fromIterable(['a', 'a', 'b', 'c', 'c']);
// Union (max multiplicity)
final union = p.union(q);
print('P ∪ Q = $union');
// Output: {a:3, b:1, c:2, d:2}
// Intersection (min multiplicity)
final intersection = p.intersection(q);
print('P ∩ Q = $intersection');
// Output: {a:2, c:1}
// Difference
final difference = p.difference(q);
print('P - Q = $difference');
// Output: {a:1, d:2}
// Sum
final sum = p.sum(q);
print('P + Q = $sum');
// Output: {a:5, b:1, c:3, d:2}
// Convert to standard set
final set = p.toSet();
print('P as Set = $set');
// Output: {a, c, d}
Mathematical Notation Reference
| Operation | Notation | Dart Method |
|---|---|---|
| Membership | x ∈ A | set.contains(x) |
| Not Member | x ∉ A | !set.contains(x) |
| Subset | A ⊆ B | a.isSubsetOf(b) |
| Proper Subset | A ⊂ B | a.isProperSubsetOf(b) |
| Superset | A ⊇ B | a.isSupersetOf(b) |
| Union | A ∪ B | SetOperations.union(a, b) |
| Intersection | A ∩ B | SetOperations.intersection(a, b) |
| Complement | A' or A̅ | SetOperations.complement(a, universal) |
| Difference | A - B | SetOperations.difference(a, b) |
| Symmetric Difference | A ⊕ B | SetOperations.symmetricDifference(a, b) |
| Cartesian Product | A × B | AdvancedSetOperations.cartesianProduct(a, b) |
| Power Set | P(A) or 2^A | set.powerSet |
| Cardinality | |A| or n(A) | set.cardinality |
| Cardinality Utility | |A| | CardinalityUtils.cardinality(a) |
| Union Cardinality | |A ∪ B| | CardinalityUtils.unionCardinality(a, b) |
| Intersection Cardinality | |A ∩ B| | SetOperations.intersection(a, b).cardinality |
| Symmetric Diff Cardinality | |A ⊕ B| | CardinalityUtils.symmetricDifferenceCardinality(a, b) |
| Power Set Cardinality | |P(A)| | CardinalityUtils.powerSetCardinality(a) |
| Empty Set | ∅ or {} | CustomSet.empty() |
| Equivalent | A ~ B | a.isEquivalentTo(b) |
| Disjoint | A // B | a.isDisjointFrom(b) |
CardinalityUtils API Reference
Basic Methods
| Method | Description | Example |
|---|---|---|
cardinality(set) |
Get number of elements | CardinalityUtils.cardinality(a) |
isEmpty(set) |
Check if set is empty | CardinalityUtils.isEmpty(a) |
isSingleton(set) |
Check if set has exactly 1 element | CardinalityUtils.isSingleton(a) |
isFinite(set) |
Check if set is finite | CardinalityUtils.isFinite(a) |
Union Cardinality Methods
| Method | Description | Formula |
|---|---|---|
unionCardinality(a, b) |
Union of 2 sets | |A| + |B| - |A ∩ B| |
unionCardinality3(a, b, c) |
Union of 3 sets | |A| + |B| + |C| - |A ∩ B| - |A ∩ C| - |B ∩ C| + |A ∩ B ∩ C| |
unionCardinalityN(sets) |
Union of n sets | Generalized Inclusion-Exclusion |
Other Cardinality Methods
| Method | Description | Formula |
|---|---|---|
symmetricDifferenceCardinality(a, b) |
Symmetric difference | |A| + |B| - 2|A ∩ B| |
differenceCardinality(a, b) |
Set difference | |A| - |A ∩ B| |
complementCardinality(a, universal) |
Complement | |U| - |A| |
cartesianProductCardinality(a, b) |
Cartesian product (2) | |A| × |B| |
cartesianProductCardinalityN(sets) |
Cartesian product (n) | |A₁| × |A₂| × ... × |Aₙ| |
powerSetCardinality(set) |
Power set | 2^|A| |
Verification Methods
| Method | Description | Returns |
|---|---|---|
verifyInclusionExclusion2(a, b) |
Verify 2-set inclusion-exclusion | bool |
verifyInclusionExclusion3(a, b, c) |
Verify 3-set inclusion-exclusion | bool |
verifyDisjointUnion(a, b) |
Verify disjoint union cardinality | bool |
Convenience Methods
| Method | Description | Equivalent To |
|---|---|---|
exactlyOne(a, b) |
Elements in exactly one set | Symmetric difference |
both(a, b) |
Elements in both sets | Intersection |
atLeastOne(a, b) |
Elements in at least one set | Union |
neither(a, b, universal) |
Elements in neither set | |U| - |A ∪ B| |
Reporting Methods
| Method | Description | Returns |
|---|---|---|
summary(a, b) |
Cardinality summary map | Map<String, int> |
printReport(a, b, title) |
Print detailed report | void |
Real-World Examples
Example 1: Student Survey
// Survey results from a dormitory
// 650 students have a dictionary
// 150 students do not have a dictionary
// 175 students have an encyclopedia
// 50 students have neither
final totalStudents = 650 + 150; // 800
final hasDictionary = 650;
final hasEncyclopedia = 175;
final hasNeither = 50;
final hasEitherOrBoth = totalStudents - hasNeither; // 750
// Students with both dictionary and encyclopedia
final hasBoth = hasDictionary + hasEncyclopedia - hasEitherOrBoth;
print('Total students: $totalStudents');
print('Students with both: $hasBoth'); // Output: 75
// Using CardinalityUtils
final universal = CustomSet<int>(List.generate(totalStudents, (i) => i + 1));
final k = CustomSet.fromPredicate(universal.elements, (x) => x <= hasDictionary);
final e = CustomSet.fromPredicate(universal.elements, (x) => x <= hasEncyclopedia);
print('Verified with CardinalityUtils: ${CardinalityUtils.both(k, e)}');
Example 2: Hardware Procurement
// Department requirements
final ti = MultiSet<String>.fromIterable([
...List.filled(100, 'PC'),
...List.filled(40, 'router'),
...List.filled(5, 'server'),
]);
final ms = MultiSet<String>.fromIterable([
...List.filled(10, 'PC'),
...List.filled(7, 'router'),
...List.filled(2, 'mainframe'),
]);
// a) Shareable resources (Union - max)
final shareable = ti.union(ms);
print('PCs needed: ${shareable.multiplicity('PC')}'); // Output: 100
// b) Non-shareable resources (Sum)
final nonShareable = ti.sum(ms);
print('Total PCs: ${nonShareable.multiplicity('PC')}'); // Output: 110
// c) MS-only requirements (Difference)
final msOnly = ms.difference(ti);
print('Mainframes: ${msOnly.multiplicity('mainframe')}'); // Output: 2
Example 3: Divisibility Problem
// How many numbers from 1 to 100 are divisible by 3 or 5?
final universal = CustomSet<int>(List.generate(100, (i) => i + 1));
final div3 = CustomSet.fromPredicate(
universal.elements,
(x) => x % 3 == 0,
);
final div5 = CustomSet.fromPredicate(
universal.elements,
(x) => x % 5 == 0,
);
// Using Inclusion-Exclusion Principle
final count = CardinalityUtils.unionCardinality(div3, div5);
print('Numbers divisible by 3 or 5: $count'); // Output: 47
// Verification
print('Verified: ${CardinalityUtils.verifyInclusionExclusion2(div3, div5)}');
// Detailed breakdown
print('Divisible by 3: ${div3.cardinality}'); // Output: 33
print('Divisible by 5: ${div5.cardinality}'); // Output: 20
print('Divisible by both: ${CardinalityUtils.both(div3, div5)}'); // Output: 6
Example 4: Cardinality Report
final a = CustomSet<int>([1, 2, 3, 4, 5]);
final b = CustomSet<int>([4, 5, 6, 7, 8]);
final universal = CustomSet<int>(List.generate(10, (i) => i + 1));
// Print detailed cardinality report
CardinalityUtils.printReport(a, b, title: 'Set Analysis Report');
/*
Output:
==================================================
Set Analysis Report
==================================================
|A| = 5
|B| = 5
|A ∪ B| = 8
|A ∩ B| = 2
|A - B| = 3
|B - A| = 3
|A ⊕ B| = 6
Only in A = 3
Only in B = 3
In both = 2
In either or both = 8
==================================================
*/
// Get summary as map
final summary = CardinalityUtils.summary(a, b);
print('Union: ${summary['union']}');
print('Intersection: ${summary['intersection']}');
Running Tests
# Run all tests
dart test
# Run with coverage
dart test --coverage=coverage
# Generate coverage report
genhtml coverage/lcov.info -o coverage/html
Running Examples
# Run the main example
dart run example/main.dart
# Run specific example
dart run example/advanced_operations.dart
# Run cardinality examples
dart run example/cardinality_operations.dart
Generating Documentation
# Generate API documentation
dart doc
# Serve documentation locally
dart doc --serve
Project Structure
set_theory/
├── lib/
│ ├── set_theory.dart # Main library export
│ ├── models/
│ │ ├── custom_set.dart # CustomSet class
│ │ └── multiset.dart # MultiSet class
│ ├── operations/
│ │ ├── set_operations.dart # Basic set operations
│ │ ├── advanced_set_operations.dart # Advanced operations
│ │ └── set_laws.dart # Set law verification
│ └── utils/
│ └── cardinality.dart # Cardinality utilities
├── test/
│ └── set_theory_test.dart # Unit tests
├── example/
│ ├── main.dart # Main example
│ ├── set_operations.dart # Basic operations example
│ ├── advanced_set_operations.dart # Advanced operations example
│ ├── cardinality_operations.dart # Cardinality examples
│ └── real_world.dart # Real-world examples
├── pubspec.yaml # Package configuration
├── CHANGELOG.md # Version history
├── LICENSE # MIT License
└── README.md # This file
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Based on standard set theory principles from discrete mathematics
- Inspired by mathematical notation used in academic literature
- Built with Dart's strong type system for type safety
- Cardinality utilities follow Inclusion-Exclusion Principle standards
Support
For issues and feature requests, please use the GitHub Issues page.
For questions about set theory concepts, please refer to:
- Discrete Mathematics and Its Applications by Kenneth Rosen
- Introduction to Set Theory by Karel Hrbacek and Thomas Jech
Version History
See CHANGELOG.md for detailed version history.
Libraries
- models/custom_set
- models/multiset
- operations/advanced_set_operations
- operations/set_laws
- operations/set_operations
- set_theory
- A comprehensive library for Set Theory operations in Dart.
- utils/cardinality
- Utility classes and functions for calculating and working with set cardinality.