discrete-math-toolkit 0.2.0
A comprehensive Python package for discrete mathematics automation
License: MIT
Requires Python: >=3.8
Keywords: discrete-mathematics, graph-theory, combinatorics, logic, set-theory, number-theory, relations, mathematics, education

# 🧮 Discrete Math Toolkit

**Your Python companion for discrete mathematics!**

Whether you're a student tackling homework, an educator creating examples, or a researcher exploring mathematical concepts, this toolkit automates the tedious calculations so you can focus on understanding the concepts.

## 🎯 What Can You Do With This?

### For Students 📚
- ✅ Verify your homework answers instantly
- ✅ Generate truth tables for logic assignments
- ✅ Calculate permutations and combinations without manual work
- ✅ Visualize graph algorithms step-by-step
- ✅ Check if your relations are reflexive, symmetric, or transitive

### For Educators 👨‍🏫
- ✅ Generate examples and test cases quickly
- ✅ Create consistent problem sets
- ✅ Demonstrate algorithms programmatically
- ✅ Build interactive demonstrations

### For Developers 🚀
- ✅ Integrate discrete math operations into your applications
- ✅ Build educational tools and games
- ✅ Prototype algorithms before optimization
- ✅ Add mathematical validation to your systems

## 📦 Installation

Super simple! Just one command:

```bash
pip install discrete-math-toolkit
```

That's it! No complicated setup, no additional dependencies to worry about.

## 🎯 Two Ways to Use This Library

### 1. **Python API** (For Developers)
Import and use the functions in your Python code:
```python
from discrete_math import combinatorics
result = combinatorics.factorial(5)
```

### 2. **Command Line Interface (CLI)** (For Everyone!)
Use the `dmath` command directly from your terminal - **perfect for non-technical users**:
```bash
dmath factorial 5
# Output: 120
```

**✨ The CLI makes discrete math accessible to everyone - no coding required!**

# 🖥️ Complete CLI Reference Guide

The Discrete Math Toolkit includes a comprehensive CLI that allows both technical and non-technical users to access all library functions directly from the command line.

## Basic CLI Usage

```bash
dmath <function-name> <arguments>
```

To see all available functions:
```bash
dmath --help
```

To get help for a specific function:
```bash
dmath <function-name> --help
```

---

## 📊 Combinatorics CLI Commands

| Function | Python Code | CLI Command |
|----------|-------------|-------------|
| Factorial | `factorial(5)` | `dmath factorial 5` |
| Permutations | `permutations(5, 2)` | `dmath permutations 5 2` |
| Combinations | `combinations(5, 2)` | `dmath combinations 5 2` |
| Binomial Coefficient | `binomial_coefficient(5, 2)` | `dmath binomial 5 2` |
| Permutations with Repetition | `permutations_with_repetition(3, 2)` | `dmath perm-rep 3 2` |
| Combinations with Repetition | `combinations_with_repetition(3, 2)` | `dmath comb-rep 3 2` |
| Pascal's Triangle | `pascals_triangle(5)` | `dmath pascal 5` |
| Catalan Number | `catalan_number(4)` | `dmath catalan 4` |
| Stirling Number | `stirling_second_kind(5, 2)` | `dmath stirling 5 2` |
| Bell Number | `bell_number(4)` | `dmath bell 4` |
| Derangements | `derangements(4)` | `dmath derangements 4` |
| Fibonacci | `fibonacci(10)` | `dmath fibonacci 10` |
| Multinomial | `multinomial_coefficient([2,3,4])` | `dmath multinomial 2 3 4` |

### CLI Examples - Combinatorics

```bash
# Factorial
dmath factorial 5
# Output: 120

# Permutations P(5,2)
dmath permutations 5 2
# Output: 20

# Combinations C(10,3)
dmath combinations 10 3
# Output: 120

# Pascal's Triangle with 5 rows
dmath pascal 5

# Catalan number
dmath catalan 4
# Output: 14

# Fibonacci
dmath fibonacci 10
# Output: 55

# Generate permutations
dmath gen-perms "[1,2,3]" 2
# Output: [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

# Generate combinations
dmath gen-combs "[1,2,3,4]" 2
# Output: [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]

# Generate combinations with repetition
dmath gen-combs-rep "[1,2]" 2
# Output: [(1, 1), (1, 2), (2, 2)]
```

---

## 🔢 Number Theory CLI Commands

| Function | Python Code | CLI Command |
|----------|-------------|-------------|
| GCD | `gcd(48, 18)` | `dmath gcd 48 18` |
| LCM | `lcm(12, 18)` | `dmath lcm 12 18` |
| Extended GCD | `extended_gcd(30, 20)` | `dmath extended-gcd 30 20` |
| Is Prime | `is_prime(17)` | `dmath is-prime 17` |
| Prime Factorization | `prime_factorization(60)` | `dmath prime-factors 60` |
| Primes Up To N | `sieve_of_eratosthenes(20)` | `dmath primes-upto 20` |
| Modular Inverse | `mod_inverse(3, 11)` | `dmath mod-inverse 3 11` |
| Modular Exponentiation | `mod_exp(2, 10, 1000)` | `dmath mod-exp 2 10 1000` |
| Euler's Totient | `euler_totient(9)` | `dmath euler-phi 9` |
| Chinese Remainder Theorem | `chinese_remainder_theorem([2,3,2], [3,5,7])` | `dmath crt "[2,3,2]" "[3,5,7]"` |
| Is Coprime | `is_coprime(15, 28)` | `dmath is-coprime 15 28` |
| Divisors | `divisors(12)` | `dmath divisors 12` |
| Sum of Divisors | `sum_of_divisors(12)` | `dmath sum-divisors 12` |
| Is Perfect Number | `is_perfect_number(6)` | `dmath is-perfect 6` |

### CLI Examples - Number Theory

```bash
# GCD
dmath gcd 48 18
# Output: 6

# LCM
dmath lcm 12 18
# Output: 36

# Extended GCD (returns gcd, x, y where ax + by = gcd)
dmath extended-gcd 30 20
# Output: (10, 1, -1)

# Check if prime
dmath is-prime 17
# Output: True

# Prime factorization
dmath prime-factors 60
# Output: {2: 2, 3: 1, 5: 1}  (60 = 2² × 3 × 5)

# Find all primes up to N
dmath primes-upto 20
# Output: [2, 3, 5, 7, 11, 13, 17, 19]

# Modular inverse
dmath mod-inverse 3 11
# Output: 4  (because 3 × 4 ≡ 1 (mod 11))

# Modular exponentiation
dmath mod-exp 2 10 1000
# Output: 24  (2^10 mod 1000)

# Euler's totient
dmath euler-phi 9
# Output: 6

# Chinese Remainder Theorem
dmath crt "[2,3,2]" "[3,5,7]"
# Output: 23

# Find divisors
dmath divisors 12
# Output: [1, 2, 3, 4, 6, 12]

# Check if perfect number
dmath is-perfect 6
# Output: True
```

---

## 🧠 Logic CLI Commands

| Function | Python Code | CLI Command |
|----------|-------------|-------------|
| Truth Table | `generate_truth_table("p AND q")` | `dmath truth-table "p AND q"` |
| Is Tautology | `is_tautology("p OR (NOT p)")` | `dmath is-tautology "p OR (NOT p)"` |
| Is Contradiction | `is_contradiction("p AND (NOT p)")` | `dmath is-contradiction "p AND (NOT p)"` |
| Is Contingency | `is_contingency("p AND q")` | `dmath is-contingency "p AND q"` |
| Convert to CNF | `convert_to_cnf("p IMPLIES q")` | `dmath to-cnf "p IMPLIES q"` |
| Convert to DNF | `convert_to_dnf("p IMPLIES q")` | `dmath to-dnf "p IMPLIES q"` |
| Logical Equivalence | `are_equivalent(expr1, expr2)` | `dmath logic-equiv "p IMPLIES q" "(NOT p) OR q"` |
| Simplify | `simplify("p AND p")` | `dmath simplify-logic "p AND p"` |
| Evaluate | `evaluate("p AND q", {"p": True, "q": False})` | `dmath eval-logic "p AND q" '{"p": true, "q": false}'` |
| Minterms | `get_minterms("p OR q")` | `dmath minterms "p OR q"` |
| Maxterms | `get_maxterms("p OR q")` | `dmath maxterms "p OR q"` |

### CLI Examples - Logic

```bash
# Generate truth table
dmath truth-table "p AND q"
dmath truth-table "p IMPLIES q"
dmath truth-table "(p OR q) AND (NOT r)"

# Check if tautology (always true)
dmath is-tautology "p OR (NOT p)"
# Output: True

# Check if contradiction (always false)
dmath is-contradiction "p AND (NOT p)"
# Output: True

# Check if contingency
dmath is-contingency "p AND q"
# Output: True

# Convert to CNF
dmath to-cnf "p IMPLIES q"
# Output: (~p) | q

# Convert to DNF
dmath to-dnf "p IMPLIES q"
# Output: (~p) | q

# Check logical equivalence
dmath logic-equiv "p IMPLIES q" "(NOT p) OR q"
# Output: True

# Simplify expression
dmath simplify-logic "p AND p"
# Output: p

# Evaluate with values
dmath eval-logic "p AND q" '{"p": true, "q": false}'
# Output: False

# Get minterms (rows where True)
dmath minterms "p OR q"
# Output: [1, 2, 3]

# Get maxterms (rows where False)
dmath maxterms "p OR q"
# Output: [0]
```

**Supported Logical Operators in CLI:**
- `AND`, `&`, `∧`
- `OR`, `|`, `∨`
- `NOT`, `~`, `¬`
- `IMPLIES`, `->`
- `IFF`, `<->`
- `XOR`, `^`

---

## 📦 Set Theory CLI Commands

| Function | Python Code | CLI Command |
|----------|-------------|-------------|
| Union | `union({1,2,3}, {3,4,5})` | `dmath set-union "{1,2,3}" "{3,4,5}"` |
| Intersection | `intersection({1,2,3}, {2,3,4})` | `dmath set-intersect "{1,2,3}" "{2,3,4}"` |
| Difference | `difference({1,2,3}, {2,3,4})` | `dmath set-diff "{1,2,3}" "{2,3,4}"` |
| Symmetric Difference | `symmetric_difference({1,2,3}, {2,3,4})` | `dmath set-sym-diff "{1,2,3}" "{2,3,4}"` |
| Complement | `complement({1,2}, {1,2,3,4,5})` | `dmath set-complement "{1,2}" "{1,2,3,4,5}"` |
| Power Set | `power_set({1,2,3})` | `dmath power-set "{1,2,3}"` |
| Cartesian Product | `cartesian_product({1,2}, {3,4})` | `dmath cartesian "{1,2}" "{3,4}"` |
| Is Subset | `is_subset({1,2}, {1,2,3,4})` | `dmath is-subset "{1,2}" "{1,2,3,4}"` |
| Is Proper Subset | `is_proper_subset({1,2}, {1,2,3})` | `dmath is-proper-subset "{1,2}" "{1,2,3}"` |
| Is Superset | `is_superset({1,2,3,4}, {1,2})` | `dmath is-superset "{1,2,3,4}" "{1,2}"` |
| Is Disjoint | `is_disjoint({1,2}, {3,4})` | `dmath is-disjoint "{1,2}" "{3,4}"` |
| Cardinality | `cardinality({1,2,3,4,5})` | `dmath cardinality "{1,2,3,4,5}"` |
| Is Partition | `partition({1,2,3,4}, {1,2}, {3}, {4})` | `dmath is-partition "{1,2,3,4}" "{1,2}" "{3}" "{4}"` |
| Sets Equal | `are_equal({1,2,3}, {3,2,1})` | `dmath sets-equal "{1,2,3}" "{3,2,1}"` |
| Power Set Size | `power_set_cardinality({1,2,3})` | `dmath power-set-size "{1,2,3}"` |

### CLI Examples - Set Theory

```bash
# Union
dmath set-union "{1,2,3}" "{3,4,5}"
# Output: [1, 2, 3, 4, 5]

# Multiple sets union
dmath set-union "{1,2}" "{2,3}" "{3,4}"
# Output: [1, 2, 3, 4]

# Intersection
dmath set-intersect "{1,2,3}" "{2,3,4}"
# Output: [2, 3]

# Difference (A - B)
dmath set-diff "{1,2,3}" "{2,3,4}"
# Output: [1]

# Symmetric Difference
dmath set-sym-diff "{1,2,3}" "{2,3,4}"
# Output: [1, 4]

# Complement
dmath set-complement "{1,2}" "{1,2,3,4,5}"
# Output: [3, 4, 5]

# Power Set
dmath power-set "{1,2,3}"
# Output: All subsets including empty set

# Cartesian Product
dmath cartesian "{1,2}" "{3,4}"
# Output: [(1, 3), (1, 4), (2, 3), (2, 4)]

# Cartesian Product of N sets
dmath cartesian-n "{1,2}" "{a,b}" "{x,y}"
# Output: All n-tuples from the product

# Check subset
dmath is-subset "{1,2}" "{1,2,3,4}"
# Output: True

# Check proper subset
dmath is-proper-subset "{1,2}" "{1,2,3}"
# Output: True

# Check superset
dmath is-superset "{1,2,3,4}" "{1,2}"
# Output: True

# Check disjoint
dmath is-disjoint "{1,2}" "{3,4}"
# Output: True

# Cardinality
dmath cardinality "{1,2,3,4,5}"
# Output: 5

# Check partition
dmath is-partition "{1,2,3,4}" "{1,2}" "{3}" "{4}"
# Output: True

# Check sets equal
dmath sets-equal "{1,2,3}" "{3,2,1}"
# Output: True

# Power set cardinality
dmath power-set-size "{1,2,3}"
# Output: 8  (2^3)
```

---

## 🔗 Relations CLI Commands

| Function | Python Code | CLI Command |
|----------|-------------|-------------|
| Is Reflexive | `is_reflexive(R, domain)` | `dmath is-reflexive "{(1,1),(2,2),(3,3)}" "{1,2,3}"` |
| Is Symmetric | `is_symmetric(R)` | `dmath is-symmetric "{(1,2),(2,1),(3,3)}"` |
| Is Antisymmetric | `is_antisymmetric(R)` | `dmath is-antisymmetric "{(1,2),(2,3),(1,1)}"` |
| Is Transitive | `is_transitive(R)` | `dmath is-transitive "{(1,2),(2,3),(1,3)}"` |
| Is Equivalence | `is_equivalence_relation(R, domain)` | `dmath is-equivalence "{(1,1),(2,2),(1,2),(2,1)}" "{1,2}"` |
| Is Partial Order | `is_partial_order(R, domain)` | `dmath is-partial-order "{(1,1),(2,2),(1,2)}" "{1,2}"` |
| Reflexive Closure | `reflexive_closure(R, domain)` | `dmath reflexive-closure "{(1,2),(2,3)}" "{1,2,3}"` |
| Symmetric Closure | `symmetric_closure(R)` | `dmath symmetric-closure "{(1,2),(2,3)}"` |
| Transitive Closure | `transitive_closure(R)` | `dmath transitive-closure "{(1,2),(2,3)}"` |
| Equivalence Classes | `equivalence_classes(R, domain)` | `dmath equiv-classes "{(1,1),(2,2),(1,2),(2,1)}" "{1,2}"` |
| Compose Relations | `compose(R1, R2)` | `dmath compose-rel "{(1,2),(2,3)}" "{(2,4),(3,5)}"` |
| Inverse Relation | `inverse_relation(R)` | `dmath inverse-rel "{(1,2),(2,3),(3,4)}"` |
| Relation Domain | `get_domain(R)` | `dmath rel-domain "{(1,2),(2,3),(3,4)}"` |
| Relation Range | `get_range(R)` | `dmath rel-range "{(1,2),(2,3),(3,4)}"` |
| Relation Matrix | `relation_matrix(R, elements)` | `dmath rel-matrix "{(0,0),(0,1),(1,1)}" "[0,1,2]"` |

### CLI Examples - Relations

```bash
# Check reflexive
dmath is-reflexive "{(1,1),(2,2),(3,3)}" "{1,2,3}"
# Output: True

# Check symmetric
dmath is-symmetric "{(1,2),(2,1),(3,3)}"
# Output: True

# Check antisymmetric
dmath is-antisymmetric "{(1,2),(2,3),(1,1)}"
# Output: True

# Check transitive
dmath is-transitive "{(1,2),(2,3),(1,3)}"
# Output: True

# Check equivalence relation
dmath is-equivalence "{(1,1),(2,2),(3,3),(1,2),(2,1)}" "{1,2,3}"
# Output: False (not transitive)

# Check partial order
dmath is-partial-order "{(1,1),(2,2),(3,3),(1,2),(2,3),(1,3)}" "{1,2,3}"
# Output: True

# Reflexive closure
dmath reflexive-closure "{(1,2),(2,3)}" "{1,2,3}"
# Output: {(1,1),(2,2),(3,3),(1,2),(2,3)}

# Symmetric closure
dmath symmetric-closure "{(1,2),(2,3)}"
# Output: {(1,2),(2,1),(2,3),(3,2)}

# Transitive closure
dmath transitive-closure "{(1,2),(2,3)}"
# Output: {(1,2),(2,3),(1,3)}

# Equivalence classes
dmath equiv-classes "{(1,1),(2,2),(3,3),(1,2),(2,1)}" "{1,2,3}"
# Output: [{1, 2}, {3}]

# Compose relations
dmath compose-rel "{(1,2),(2,3)}" "{(2,4),(3,5)}"
# Output: Composed relation

# Inverse relation
dmath inverse-rel "{(1,2),(2,3),(3,4)}"
# Output: {(2,1),(3,2),(4,3)}

# Relation domain
dmath rel-domain "{(1,2),(2,3),(3,4)}"
# Output: {1, 2, 3}

# Relation range
dmath rel-range "{(1,2),(2,3),(3,4)}"
# Output: {2, 3, 4}

# Relation matrix
dmath rel-matrix "{(0,0),(0,1),(1,1)}" "[0,1,2]"
# Output: [[1, 1, 0], [0, 1, 0], [0, 0, 0]]
```

---

## 🎯 Functions CLI Commands

| Function | Python Code | CLI Command |
|----------|-------------|-------------|
| Is Function | `is_function(R, domain)` | `dmath is-function "{(1,2),(2,3),(3,4)}" "{1,2,3}"` |
| Is Injective | `is_injective(f)` | `dmath is-injective "{(1,2),(2,3),(3,4)}"` |
| Is Surjective | `is_surjective(f, codomain)` | `dmath is-surjective "{(1,'a'),(2,'b')}" "{'a','b'}"` |
| Is Bijective | `is_bijective(f, domain, codomain)` | `dmath is-bijective "{(1,2),(2,3)}" "{1,2}" "{2,3}"` |
| Compose Functions | `compose_functions(g, f)` | `dmath compose-func "{(1,2),(2,3)}" "{(0,1),(1,2)}"` |
| Inverse Function | `inverse_function(f, domain, codomain)` | `dmath inverse-func "{(1,2),(2,3),(3,4)}"` |
| Function Domain | `get_domain(f)` | `dmath func-domain "{(1,2),(2,3),(3,4)}"` |
| Function Range | `get_range(f)` | `dmath func-range "{(1,2),(2,3),(3,4)}"` |
| Function to Dict | `function_to_dict(f)` | `dmath func-to-dict "{(1,2),(2,3),(3,4)}"` |

### CLI Examples - Functions

```bash
# Check if relation is a function
dmath is-function "{(1,2),(2,3),(3,4)}" "{1,2,3}"
# Output: True

dmath is-function "{(1,2),(1,3)}" "{1,2}"
# Output: False (one input maps to multiple outputs)

# Check injective (one-to-one)
dmath is-injective "{(1,2),(2,3),(3,4)}"
# Output: True

# Check surjective (onto)
dmath is-surjective "{(1,'a'),(2,'b')}" "{'a','b'}"
# Output: True

# Check bijective
dmath is-bijective "{(1,2),(2,3),(3,4)}" "{1,2,3}" "{2,3,4}"
# Output: True

# Compose functions
dmath compose-func "{(1,2),(2,3),(3,4)}" "{(0,1),(1,2),(2,3)}"
# Output: {(0, 2), (1, 3), (2, 4)}

# Inverse function
dmath inverse-func "{(1,2),(2,3),(3,4)}"
# Output: {(2,1),(3,2),(4,3)}

# Get function domain
dmath func-domain "{(1,2),(2,3),(3,4)}"
# Output: {1, 2, 3}

# Get function range
dmath func-range "{(1,2),(2,3),(3,4)}"
# Output: {2, 3, 4}

# Convert function to dictionary
dmath func-to-dict "{(1,2),(2,3),(3,4)}"
# Output: {1: 2, 2: 3, 3: 4}
```

---

## 📈 Graph CLI Commands

| Function | Python Code | CLI Command |
|----------|-------------|-------------|
| Complete Graph | `Graph.complete_graph(5)` | `dmath complete-graph 5` |
| Cycle Graph | `Graph.cycle_graph(4)` | `dmath cycle-graph 4` |
| Path Graph | `Graph.path_graph(3)` | `dmath path-graph 3` |
| BFS Traversal | `graph.bfs(start)` | `dmath graph-bfs "[(0,1),(1,2)]" 0` |
| DFS Traversal | `graph.dfs(start)` | `dmath graph-dfs "[(0,1),(1,2)]" 0` |
| Is Connected | `graph.is_connected()` | `dmath graph-connected "[(0,1),(1,2)]"` |
| Has Cycle | `graph.has_cycle()` | `dmath graph-cycle "[(0,1),(1,2),(2,0)]"` |
| Is Bipartite | `graph.is_bipartite()` | `dmath graph-bipartite "[(0,1),(1,2)]"` |
| Shortest Path | `graph.shortest_path(s, t)` | `dmath graph-shortest-path "[(0,1),(1,2)]" 0 2` |
| Topological Sort | `graph.topological_sort()` | `dmath graph-topo-sort "[(0,1),(1,2)]"` |

### CLI Examples - Graphs

```bash
# Create complete graph K_5
dmath complete-graph 5

# Create cycle graph C_4
dmath cycle-graph 4

# Create path graph P_3
dmath path-graph 3

# BFS traversal
dmath graph-bfs "[(0,1),(1,2),(2,3),(0,3)]" 0
# Output: [0, 1, 3, 2]

# DFS traversal
dmath graph-dfs "[(0,1),(1,2),(2,3),(0,3)]" 0
# Output: [0, 1, 2, 3]

# Check if connected
dmath graph-connected "[(0,1),(1,2),(2,3)]"
# Output: True

# Check if has cycle
dmath graph-cycle "[(0,1),(1,2),(2,0)]"
# Output: True

# Check if bipartite
dmath graph-bipartite "[(0,1),(1,2),(2,3),(3,0)]"
# Output: True

# Shortest path
dmath graph-shortest-path "[(0,1),(1,2),(2,3),(0,3)]" 0 3
# Output: Path: [0, 3], Distance: 1.0

# Topological sort (for DAGs)
dmath graph-topo-sort "[(0,1),(1,2),(0,2)]"
# Output: [0, 1, 2]
```

---

## 💡 CLI Tips for Non-Technical Users

### Understanding Input Notation

| Type | Format | Example |
|------|--------|---------|
| Sets | Curly braces | `"{1,2,3}"` |
| Relations/Functions | Set of pairs | `"{(1,2),(2,3)}"` |
| Lists | Square brackets | `"[1,2,3]"` |
| Empty set | Empty braces | `"{}"` |

### Common Mistakes to Avoid

1. **Forgetting quotes for sets**: Use `"{1,2,3}"` not `{1,2,3}`
2. **Wrong syntax for relations**: Use `"{(1,2),(2,3)}"` not `{(1,2),(2,3)}`
3. **Logical operators**: Use `"p AND q"` not `"p && q"`

### Getting Help

```bash
# See all commands
dmath --help

# Get help for a specific command
dmath factorial --help
dmath is-prime --help
```

---

## 🎓 CLI Educational Examples

### Example 1: Homework Helper - Set Theory
```bash
# Given A = {1,2,3,4,5} and B = {4,5,6,7}
# Find: A ∪ B, A ∩ B, A - B

dmath set-union "{1,2,3,4,5}" "{4,5,6,7}"
# Output: [1, 2, 3, 4, 5, 6, 7]

dmath set-intersect "{1,2,3,4,5}" "{4,5,6,7}"
# Output: [4, 5]

dmath set-diff "{1,2,3,4,5}" "{4,5,6,7}"
# Output: [1, 2, 3]
```

### Example 2: Combinatorics Problems
```bash
# How many ways to choose 3 items from 10?
dmath combinations 10 3
# Output: 120

# How many ways to arrange 5 items?
dmath permutations 5
# Output: 120

# Calculate 10!
dmath factorial 10
# Output: 3628800
```

### Example 3: Number Theory
```bash
# Check if numbers are prime
dmath is-prime 17
# Output: True

dmath is-prime 20
# Output: False

# Find GCD and LCM
dmath gcd 48 18
# Output: 6

dmath lcm 48 18
# Output: 144
```

### Example 4: Logic Verification
```bash
# Check if an expression is always true
dmath is-tautology "p OR (NOT p)"
# Output: True

# Check logical equivalence
dmath logic-equiv "p IMPLIES q" "(NOT p) OR q"
# Output: True
```

---

## 🎯 Benefits of CLI Access

✅ **Easy for beginners** - No Python knowledge required  
✅ **Quick calculations** - Run functions directly from terminal  
✅ **Educational tool** - Perfect for learning discrete mathematics  
✅ **Scriptable** - Can be used in shell scripts and automation  
✅ **Cross-platform** - Works on Windows, Mac, and Linux



## 🚀 Quick Start - Get Results in 30 Seconds

```python
from discrete_math import logic, sets, combinatorics

# Example 1: Check if a logical statement is always true
print(logic.is_tautology("p OR (NOT p)"))  # True - this is always true!

# Example 2: Find what elements two sets share
students_in_math = {1, 2, 3, 4, 5}
students_in_cs = {3, 4, 5, 6, 7}
print(sets.intersection(students_in_math, students_in_cs))  # {3, 4, 5}

# Example 3: How many ways can you choose 3 people from 10?
print(combinatorics.combinations(10, 3))  # 120 different ways!
```

## 📚 Complete Feature Guide

---
## 1️⃣ Logic Module – Work with Logical Statements

**What it does:**  
Analyze propositional logic expressions, generate truth tables, evaluate expressions, check logical properties, convert to normal forms, and extract minterms/maxterms.

This module is ideal for **Discrete Mathematics**, **Logic Design**, and **Computer Organization** students.

---

## 🔹 Supported Logical Operators

| Operator | Syntax |
|--------|-------|
| AND | `AND`, `&`, `∧` |
| OR | `OR`, `|`, `∨` |
| NOT | `NOT`, `~`, `¬` |
| IMPLIES | `IMPLIES`, `->` |
| IFF (↔) | `IFF`, `<->` |
| XOR | `XOR`, `^` |

---

## 📘 Example Usage

```python
from discrete_math.logic import *
````


## ✅ 1. Generate Truth Tables

```python

table = generate_truth_table("p AND q")
print(table)
```

**Output:**

```text
[
 {'p': False, 'q': False, 'result': False},
 {'p': False, 'q': True, 'result': False},
 {'p': True, 'q': False, 'result': False},
 {'p': True, 'q': True, 'result': True}
]
```

📌 *Useful for understanding all possible outcomes of a logical expression.*

---

## ✅ 2. Check Logical Properties

### 🔹 Tautology (Always True)

```python
print(is_tautology("p OR (NOT p)"))
```

✔️ Output:

```text
True
```

---

### 🔹 Contradiction (Always False)

```python
print(is_contradiction("p AND (NOT p)"))
```

✔️ Output:

```text
True
```

---

### 🔹 Contingency (Sometimes True, Sometimes False)

```python
print(is_contingency("p AND q"))
```

✔️ Output:

```text
True
```

---

## ✅ 3. Evaluate an Expression with Given Values

```python
result = evaluate("p AND q", {"p": True, "q": False})
print(result)
```

✔️ Output:

```text
False
```

📌 *Helpful in exams and quick verification.*

---

## ✅ 4. Convert to Normal Forms

### 🔹 Conjunctive Normal Form (CNF)

```python
cnf = convert_to_cnf("(p OR q) IMPLIES r")
print(cnf)
```

✔️ Output:

```text
(~p | r) & (~q | r)
```

---

### 🔹 Disjunctive Normal Form (DNF)

```python
dnf = convert_to_dnf("(p AND q) OR (p AND r)")
print(dnf)
```

✔️ Output:

```text
p & (q | r)
```

---

## ✅ 5. Simplify Logical Expressions

```python
simple = simplify("(p AND p) OR (q AND True)")
print(simple)
```

✔️ Output:

```text
p | q
```

📌 *Applies logical identities automatically.*

---

## ✅ 6. Check Logical Equivalence

```python
expr1 = "p IMPLIES q"
expr2 = "(NOT p) OR q"

print(are_equivalent(expr1, expr2))
```

✔️ Output:

```text
True
```

📌 *Confirms whether two expressions mean the same thing.*

---

## ✅ 7. Find Minterms

```python
print(get_minterms("p OR q"))
```

✔️ Output:

```text
[1, 2, 3]
```

📌 *Indexes represent rows where the expression is TRUE.*

---

## ✅ 8. Find Maxterms

```python
print(get_maxterms("p OR q"))
```

✔️ Output:

```text
[0]
```

📌 *Indexes represent rows where the expression is FALSE.*

---

## 🎓 Student Tip

* Use **truth tables** to verify exam answers
* Use **CNF/DNF** for SAT solvers and logic circuits
* Use **minterms/maxterms** in Boolean algebra & K-maps

---


## 2️⃣ Sets Module – Master Set Operations

**What it does:**  
Perform all fundamental and advanced set theory operations such as union, intersection, difference, power sets, Cartesian products, partitions, and set relationships.

This module is ideal for **Discrete Mathematics**, **Computer Science**, and **Logic Foundations**.

---

## 📘 Example Usage

```python
from discrete_math.sets import *
````

---

## ✅ 1. Basic Set Operations

### 🔹 Union

```python
result = union({1, 2}, {2, 3}, {3, 4})
print(result)
```

**Output:**

```text
{1, 2, 3, 4}
```

---

### 🔹 Intersection

```python
result = intersection({1, 2, 3}, {2, 3, 4})
print(result)
```

**Output:**

```text
{2, 3}
```

---

### 🔹 Difference (A − B)

```python
result = difference({1, 2, 3}, {2, 3, 4})
print(result)
```

**Output:**

```text
{1}
```

---

### 🔹 Symmetric Difference (A △ B)

```python
result = symmetric_difference({1, 2, 3}, {2, 3, 4})
print(result)
```

**Output:**

```text
{1, 4}
```

---

### 🔹 Complement

```python
universal = {1, 2, 3, 4, 5}
subset = {1, 2}
print(complement(subset, universal))
```

**Output:**

```text
{3, 4, 5}
```

---

## ✅ 2. Power Sets

### 🔹 Generate Power Set

```python
ps = power_set({1, 2})
print(ps)
```

**Output:**

```text
{frozenset(), frozenset({1}), frozenset({2}), frozenset({1, 2})}
```

📌 *Each subset is returned as a `frozenset`.*

---

### 🔹 Power Set Cardinality (Without Generating)

```python
print(power_set_cardinality({1, 2, 3}))
```

**Output:**

```text
8
```

📌 *Uses the formula: 2ⁿ*

---

## ✅ 3. Cartesian Products

### 🔹 Cartesian Product of Two Sets

```python
pairs = cartesian_product({1, 2}, {'a', 'b'})
print(pairs)
```

**Output:**

```text
{(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')}
```

---

### 🔹 Cartesian Product of N Sets

```python
result = cartesian_product_n({1, 2}, {'a', 'b'}, {True, False})
print(result)
```

📌 *Returns all possible n-tuples.*

---

## ✅ 4. Set Relationships

### 🔹 Subset (⊆)

```python
print(is_subset({1, 2}, {1, 2, 3}))
```

**Output:**

```text
True
```

---

### 🔹 Proper Subset (⊂)

```python
print(is_proper_subset({1, 2}, {1, 2, 3}))
```

**Output:**

```text
True
```

---

### 🔹 Superset (⊇)

```python
print(is_superset({1, 2, 3}, {1, 2}))
```

**Output:**

```text
True
```

---

### 🔹 Disjoint Sets

```python
print(is_disjoint({1, 2}, {3, 4}))
```

**Output:**

```text
True
```

---

### 🔹 Set Equality

```python
print(are_equal({1, 2, 3}, {3, 2, 1}))
```

**Output:**

```text
True
```

---

## ✅ 5. Cardinality

```python
print(cardinality({10, 20, 30, 40}))
```

**Output:**

```text
4
```

📌 *Returns the number of elements in a set.*

---

## ✅ 6. Partition of a Set

```python
result = partition({1, 2, 3, 4}, {1, 2}, {3}, {4})
print(result)
```

**Output:**

```text
True
```

📌 *Checks whether subsets form a valid partition.*

---

## ✅ 7. Set-Builder Notation

```python
evens = set_builder(lambda x: x % 2 == 0, {1, 2, 3, 4, 5, 6})
print(evens)
```

**Output:**

```text
{2, 4, 6}
```

📌 *Mimics mathematical set-builder notation.*


---

Got it 👍
I’ll **fix and extend your README section** so that it **covers *all* public functions** exposed by your **Combinatorics Module**, based strictly on the `__all__` list in your code.

Below is a **drop-in replacement** for your current README section, written in the **same style**, with **clear examples for every function**.

---

## 3️⃣ Combinatorics Module – Count Like a Pro

**What it does:**
Perform combinatorial calculations such as permutations, combinations, binomial coefficients, and advanced counting sequences used in probability, algorithms, and discrete mathematics.

---

### 🎓 Real-World Use Case: Counting, Probability & Algorithms

```python
from discrete_math.combinatorics import *
```

---

### 🔢 Basic Building Block

#### Factorial

```python
# 5! = 5 × 4 × 3 × 2 × 1
print(factorial(5))  # 120
```

---

### 🔁 Permutations & Combinations

#### Permutations (order matters)

```python
# Arrange 3 items from 5
print(permutations(5, 3))  # 60
```

#### Combinations (order does NOT matter)

```python
# Choose 3 students from 10
print(combinations(10, 3))  # 120
```

---

### 🔂 With Repetition Allowed

#### Permutations with repetition

```python
# 3-character password from 4 symbols (repetition allowed)
print(permutations_with_repetition(4, 3))  # 64
```

#### Combinations with repetition

```python
# Choose 3 candies from 5 types
print(combinations_with_repetition(5, 3))  # 35
```

---

### 📐 Binomial & Multinomial Coefficients

#### Binomial Coefficient

```python
# C(5,2)
print(binomial_coefficient(5, 2))  # 10
```

#### Multinomial Coefficient

```python
# Distribute items into groups of sizes 2,1,1
print(multinomial_coefficient([2, 1, 1]))  # 12
```

---

### 📊 Pascal’s Triangle

```python
triangle = pascals_triangle(5)
for row in triangle:
    print(row)

# [1]
# [1, 1]
# [1, 2, 1]
# [1, 3, 3, 1]
# [1, 4, 6, 4, 1]
```

---

### 🌱 Famous Sequences

#### Fibonacci Numbers

```python
print(fibonacci(10))  # 55
```

#### Catalan Numbers

```python
# Used in counting trees, valid parentheses, etc.
print(catalan_number(5))  # 42
```

---

### 🔄 Special Counting Problems

#### Derangements (no element in original position)

```python
# Secret Santa problem
print(derangements(4))  # 9
```

#### Stirling Numbers (Second Kind)

```python
# Partition 5 elements into 2 non-empty sets
print(stirling_second_kind(5, 2))  # 15
```

#### Bell Numbers

```python
# Number of ways to partition a set of size 4
print(bell_number(4))  # 15
```

---

### 🔁 Generators (Actual Arrangements)

#### Generate permutations

```python
for p in generate_permutations([1, 2, 3], 2):
    print(p)

# (1, 2)
# (1, 3)
# (2, 1)
# ...
```

#### Generate combinations

```python
for c in generate_combinations([1, 2, 3, 4], 2):
    print(c)
```

#### Generate combinations with repetition

```python
for c in generate_combinations_with_repetition([1, 2, 3], 2):
    print(c)
```

---

### 💡 Student Tip

* **Permutations** → order matters (rankings, passwords)
* **Combinations** → order doesn’t matter (teams, selections)
* **Catalan & Stirling numbers** often appear in **DSA, trees, and recursion problems**






## 5️⃣ Number Theory Module - Explore Number Properties

Perfect — I’ll **repeat the same process** as before 👍
Below is a **clean, complete, drop-in README.md section** for your **Number Theory Module**, **covering *every function listed in `__all__`***, written in the **same tone, structure, and teaching style** you used.

You can **copy-paste this directly** into `README.md`.

---

## 5️⃣ Number Theory Module – Explore Number Properties

**What it does:**
Work with prime numbers, divisibility, GCD/LCM, modular arithmetic, and classic number-theoretic functions used in cryptography, algorithms, and discrete mathematics.

---

### 🎓 Real-World Use Case: Cryptography, Scheduling & Mathematics

```python
from discrete_math.number_theory import *
```

---

### 🔢 Fundamental Operations

#### Greatest Common Divisor (GCD)

```python
# Simplifying fractions, checking coprimality
print(gcd(48, 18))  # 6
print(gcd(17, 19))  # 1
```

#### Least Common Multiple (LCM)

```python
# Scheduling and periodic events
print(lcm(12, 18))  # 36
print(lcm(7, 5))    # 35
```

---

### 🔁 Extended Euclidean Algorithm

```python
# Finds gcd(a, b) and x, y such that ax + by = gcd(a, b)
g, x, y = extended_gcd(30, 20)
print(g, x, y)  # 10, 1, -1
```

📌 **Used in:** Modular inverse, cryptography, Diophantine equations

---

### 🔍 Prime Number Utilities

#### Prime Test

```python
print(is_prime(17))  # True
print(is_prime(100)) # False
```

#### Prime Factorization

```python
factors = prime_factorization(60)
print(factors)  # {2: 2, 3: 1, 5: 1}
# 60 = 2² × 3¹ × 5¹
```

#### Generate Primes (Sieve of Eratosthenes)

```python
print(sieve_of_eratosthenes(30))
# [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
```

---

### 🔐 Modular Arithmetic (Cryptography Core)

#### Modular Inverse

```python
# Find x such that (a * x) % m == 1
inverse = mod_inverse(3, 11)
print(inverse)  # 4
```

⚠️ Raises error if inverse does not exist.

---

#### Fast Modular Exponentiation

```python
print(mod_exp(2, 100, 17))  # Efficient for huge powers
print(mod_exp(3, 10, 7))    # 4
```

📌 **Used in:** RSA, Diffie-Hellman, hashing

---

### 🔢 Euler’s Totient Function

```python
# Counts integers ≤ n that are coprime with n
print(euler_totient(9))   # 6
print(euler_totient(10))  # 4
```

📌 **Key idea in RSA encryption**

---

### 🧮 Chinese Remainder Theorem (CRT)

```python
# Solve:
# x ≡ 2 (mod 3)
# x ≡ 3 (mod 5)
# x ≡ 2 (mod 7)
solution = chinese_remainder_theorem([2, 3, 2], [3, 5, 7])
print(solution)  # 23
```

📌 **Used in:** Distributed systems, cryptography, time synchronization

---

### 🔗 Coprimality

```python
print(is_coprime(15, 28))  # True
print(is_coprime(15, 25))  # False
```

---

### 📐 Divisor Functions

#### All Divisors

```python
print(divisors(24))
# [1, 2, 3, 4, 6, 8, 12, 24]
```

#### Sum of Divisors

```python
print(sum_of_divisors(12))  # 28
```

---

### ⭐ Perfect Numbers

```python
print(is_perfect_number(6))   # True
print(is_perfect_number(28))  # True
print(is_perfect_number(12))  # False
```

📌 A **perfect number** equals the sum of its proper divisors.




Got it 👍
Below is the **complete, polished README.md section for the Relations Module**, written in **the same style, structure, tone, and teaching depth** as your previous modules.
It **covers *all functions listed in `__all__`*** and aligns perfectly with the code you shared.

You can **copy-paste this directly into `README.md`**.

---

## 6️⃣ Relations Module – Analyze Relationships

**What it does:**
Work with binary relations, check their properties, compute closures, and analyze structured relationships mathematically.

---

### 🎓 Real-World Use Case: Databases, Hierarchies & Graphs

```python
from discrete_math.relations import *
```

---

### 🔗 Defining a Relation

```python
# Relation R on set {1, 2, 3, 4}
# (a, b) means "a is related to b"
R = {(1, 1), (1, 2), (2, 2), (3, 3), (4, 4), (2, 3)}
domain = {1, 2, 3, 4}
```

---

### ✅ Relation Properties

#### Reflexive

```python
print(is_reflexive(R, domain))  # True
```

📌 Every element relates to itself
**Example:** “Every person knows themselves”

---

#### Symmetric

```python
print(is_symmetric(R))  # False
```

📌 If `a → b`, then `b → a`
**Example:** Friendship (symmetric), Twitter follow (not symmetric)

---

#### Antisymmetric

```python
print(is_antisymmetric(R))  # True or False depending on R
```

📌 If `a → b` and `b → a`, then `a = b`
**Used in:** Partial orders (≤)

---

#### Transitive

```python
print(is_transitive(R))  # False
```

📌 If `a → b` and `b → c`, then `a → c`
**Example:** Ancestor relationships

---

### 🟰 Special Relations

#### Equivalence Relation

```python
print(is_equivalence_relation(R, domain))
```

✔ Reflexive
✔ Symmetric
✔ Transitive

📌 **Partitions a set into equivalence classes**

---

#### Partial Order

```python
partial_order = {(1,1), (2,2), (3,3), (1,2), (2,3), (1,3)}
print(is_partial_order(partial_order, {1, 2, 3}))  # True
```

📌 **Used in:** Task scheduling, version control systems

---

### 🔁 Relation Closures

#### Reflexive Closure

```python
ref_closure = reflexive_closure(R, domain)
print(ref_closure)
```

Adds `(a, a)` for all `a ∈ domain`

---

#### Symmetric Closure

```python
sym_closure = symmetric_closure(R)
print(sym_closure)
```

Makes every relation bidirectional

---

#### Transitive Closure

```python
trans_closure = transitive_closure(R)
print(trans_closure)
```

Adds all **implied indirect relationships**

📌 Uses **Warshall’s Algorithm**

---

### 🧩 Equivalence Classes

```python
R_eq = {(1,1), (2,2), (3,3), (1,2), (2,1)}
classes = equivalence_classes(R_eq, {1, 2, 3})
print(classes)  # [{1, 2}, {3}]
```

📌 **Only valid for equivalence relations**

---

### 🔄 Relation Operations

#### Composition of Relations

```python
R1 = {(1, 2), (2, 3)}
R2 = {(0, 1), (1, 2)}
print(compose(R1, R2))  # {(0, 2), (1, 3)}
```

📌 Used in **function chaining and graph traversal**

---

#### Inverse Relation

```python
print(inverse_relation({(1, 2), (2, 3)}))
# {(2, 1), (3, 2)}
```

📌 Swaps direction of every pair

---

### 📦 Domain & Range

```python
print(get_domain(R))  # {1, 2, 3, 4}
print(get_range(R))   # {1, 2, 3, 4}
```

📌 Helps analyze inputs and outputs of relations

---

### 🧮 Matrix Representation

```python
matrix = relation_matrix({(1, 2), (2, 3)}, {1, 2, 3})
for row in matrix:
    print(row)
```

**Output:**

```
[0, 1, 0]
[0, 0, 1]
[0, 0, 0]
```

📌 **Used in:** Graph theory, adjacency matrices, algorithms


Perfect — repeating **the exact same style, depth, and structure** as your previous modules.
Below is a **clean, complete, production-ready `README.md` section** for the **Functions Module**, fully aligned with your code and `__all__`.

You can **copy-paste this directly**.

---

## 7️⃣ Functions Module – Analyze Mappings

**What it does:**
Analyze mathematical functions, verify their properties (injective, surjective, bijective), perform composition, inversion, and convert between representations.

---

### 🎓 Real-World Use Case: Data Mapping & Transformations

```python
from discrete_math.functions import *
```

---

### 🔗 Defining a Function

Functions are represented as **sets of ordered pairs** or **Python dictionaries**.

```python
# Function as a dictionary
grades = {
    101: 'A',
    102: 'B',
    103: 'A',
    104: 'C',
    105: 'B'
}

domain = {101, 102, 103, 104, 105}
codomain = {'A', 'B', 'C', 'D', 'F'}

# Convert dictionary to function form
relation = dict_to_function(grades)
```

---

### ✅ Valid Function Check

```python
print(is_function(relation, domain))  # True
```

📌 Each domain element must map to **exactly one** output.

---

### 🔍 Function Properties

#### Injective (One-to-One)

```python
print(is_injective(relation))  # False
```

📌 No two inputs share the same output
❌ Here, multiple students received `'A'`

---

#### Surjective (Onto)

```python
print(is_surjective(relation, codomain))  # False
```

📌 Every element of codomain must be used
❌ Grades `'D'` and `'F'` are unused

---

#### Bijective (One-to-One & Onto)

```python
print(is_bijective(relation, domain, codomain))  # False
```

📌 **Only bijective functions are invertible**

---

### 🔁 Function Composition

```python
# f(x) = x + 1
f = {(1, 2), (2, 3),