package formulae import ( "fmt" "strings" ) /* ---------------------------------------------------------------- * * TYPE Formula * ---------------------------------------------------------------- */ type Formula struct { kind string name string expr string valence int subformulae [](*Formula) } /* ---------------------------------------------------------------- * * METHODS * ---------------------------------------------------------------- */ func (fml *Formula) SetKind(kind string) { fml.kind = kind } func (fml Formula) GetKind() string { return fml.kind } func (fml *Formula) SetExpr(expr string) { fml.expr = expr } func (fml Formula) GetExpr() string { return fml.expr } func (fml Formula) GetName() string { return fml.name } func (fml *Formula) SetSubformulae(subFmls [](*Formula)) { fml.subformulae = subFmls fml.valence = len(subFmls) } func (fml Formula) GetSubFormulae() []Formula { var n int = fml.valence var subFmls = make([]Formula, n) for i, subFml := range fml.subformulae { subFmls[i] = *subFml } return subFmls } func (fml Formula) GetAllSubFormulae() []Formula { var subFml = fml.GetSubFormulae() var result = []Formula{fml.Copy()} for _, child := range subFml { result = append(result, child.GetAllSubFormulae()...) } return result } func (fml Formula) GetAllSubFormulaeStrict() []Formula { var subFml = fml.GetSubFormulae() var result = []Formula{} for _, child := range subFml { result = append(result, child.GetAllSubFormulae()...) } return result } func (fml Formula) GetChild(indexOpt ...int) Formula { var index int = 0 if len(indexOpt) > 0 { index = indexOpt[0] } var subFml Formula if 0 <= index && index < fml.valence { subFml = *(fml.subformulae[index]) } else { panic(fmt.Sprintf("Instance has no child of index %d !", index)) } return subFml } func (fml Formula) Pretty(preindentOpt ...string) string { var preindent string = "" if len(preindentOpt) > 0 { preindent = preindentOpt[0] } return fml.pretty(preindent, " ", "", 0) } func (fml Formula) pretty(preindent string, tab string, prepend string, depth int) string { var indent string = preindent + strings.Repeat(tab, depth) switch fml.valence { case 0: switch kind := fml.kind; kind { case "atom", "generic": return indent + prepend + kind + " " + fml.expr default: return indent + prepend + kind } default: var lines string = indent + prepend + fml.kind prepend = "|__ " for _, subFml := range fml.subformulae { lines += "\n" + subFml.pretty(preindent, tab, prepend, depth+1) } return lines } } // shallow copy func (fml Formula) Copy() Formula { return Formula{ expr: fml.expr, kind: fml.kind, valence: fml.valence, subformulae: fml.subformulae, } } func (fml Formula) Deepcopy() Formula { var subFmls = make([](*Formula), len(fml.subformulae)) for i, subFml := range fml.subformulae { subFmlCopy := subFml.Deepcopy() subFmls[i] = &subFmlCopy } return Formula{ expr: fml.expr, kind: fml.kind, valence: fml.valence, subformulae: subFmls, } } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * METHODS: Recognition of Formula-Types * ---------------------------------------------------------------- */ func (fml Formula) IsIrreducible() bool { return fml.valence == 0 } func (fml Formula) IsAtom() bool { return fml.kind == "atom" } func (fml Formula) IsPositiveLiteral() bool { return fml.IsAtom() } func (fml Formula) IsNegativeLiteral() bool { return fml.IsNegation() && fml.GetChild().IsAtom() } func (fml Formula) IsLiteral() bool { return fml.IsPositiveLiteral() || fml.IsNegativeLiteral() } func (fml Formula) IsGeneric() bool { return fml.kind == "generic" } func (fml Formula) IsTautologySymbol() bool { return fml.kind == "taut" } func (fml Formula) IsContradictionSymbol() bool { return fml.kind == "contradiction" } func (fml Formula) IsConnective() bool { return fml.valence > 0 } func (fml Formula) IsNegation() bool { return fml.kind == "not" } func (fml Formula) IsConjunction2() bool { return fml.kind == "and2" } func (fml Formula) IsConjunction() bool { return fml.kind == "and" || fml.kind == "and2" } func (fml Formula) IsDisjunction2() bool { return fml.kind == "or2" } func (fml Formula) IsDisjunction() bool { return fml.kind == "or" || fml.kind == "or2" } func (fml Formula) IsImplication() bool { return fml.kind == "implies" } func (fml Formula) IsDoubleImplication() bool { return fml.kind == "iff" }