pgdesign v0.26.0 /internal/fd
On this page

Package fd provides functional dependency primitives including closure computation, minimal cover, candidate keys, and BCNF decomposition for audit.

#internal/fd

#internal/fd

Package fd provides functional dependency primitives including closure computation, minimal cover, candidate keys, and BCNF decomposition for audit.

#FuncDep

Go go
type FuncDep struct

FuncDep represents a functional dependency X -> Y.

#Component

Go go
type Component struct

Component represents a relation produced by BCNF decomposition.

#Closure

Go go
func Closure(attrs []string, fds []FuncDep) []string

Closure computes the attribute closure of attrs under fds using Armstrong's axioms. Returns the closure set (sorted for determinism).

#MinimalCover

Go go
func MinimalCover(fds []FuncDep) []FuncDep

MinimalCover computes the minimal (canonical) cover of a set of functional dependencies. Does not merge cyclic equivalences (e.g., A->B, B->A). This is a known limitation, not a bug — the algorithm is correct for non-cyclic FD sets.

#CandidateKeys

Go go
func CandidateKeys(allAttrs []string, fds []FuncDep) [][]string

CandidateKeys finds all minimal superkeys of allAttrs under fds. Returns candidate keys sorted for determinism (each key sorted internally).

#IsSuperkey

Go go
func IsSuperkey(attrs []string, allAttrs []string, fds []FuncDep) bool

IsSuperkey returns true if Closure(attrs, fds) contains all of allAttrs.

#IsPrime

Go go
func IsPrime(attr string, candidateKeys [][]string) bool

IsPrime returns true if attr appears in any candidate key.

#BCNFDecompose

Go go
func BCNFDecompose(name string, allAttrs []string, fds []FuncDep) []Component

BCNFDecompose decomposes a relation into BCNF components. Returns one Component per BCNF sub-relation, with names derived from the original name (e.g., "orders_1", "orders_2").

#IsLosslessJoin

Go go
func IsLosslessJoin(r1, r2 []string, allAttrs []string, fds []FuncDep) bool

IsLosslessJoin checks whether decomposing into r1 and r2 is lossless under the given FDs. The decomposition is lossless if the closure of (r1 intersect r2) contains all of r1 or all of r2.

#PreservesDependencies

Go go
func PreservesDependencies(original []FuncDep, components []Component) (preserved bool, lost []FuncDep)

PreservesDependencies checks whether the projected FDs in the given components preserve all original FDs. Returns true if all are preserved, along with any lost FDs (with multi-attribute dependents merged).

#ArmstrongRelation

Go go
func ArmstrongRelation(allAttrs []string, fds []FuncDep, violating FuncDep) []map[string]string

ArmstrongRelation generates a small counterexample table showing redundancy for a specific FD X->A in relation to the full attribute set. Two rows agree on X (and A, since X determines A) but differ on other attributes, making the redundancy visible. Cap at 10 rows.

#FormatRelation

Go go
func FormatRelation(allAttrs []string, rows []map[string]string) string

FormatRelation formats rows as a text table for diagnostic output.

#FuncDep.String

Go go
func (f FuncDep) String() string

String formats the FD as "{A, B} -> {C, D}".

Search