logik2021/codego/aussagenlogik/formulae/formulae_basic.go

152 lines
4.5 KiB
Go

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" }