master > master: codego - auslagern, erzeugungsmethode verbessert, SyntaxBaum -> Formula
This commit is contained in:
283
codego/aussagenlogik/formulae/formulae.go
Normal file
283
codego/aussagenlogik/formulae/formulae.go
Normal file
@@ -0,0 +1,283 @@
|
||||
package formulae
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* TYPE Formula
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
type Formula struct {
|
||||
kind 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) SetSubformulae(children [](*Formula)) {
|
||||
fml.subformulae = children
|
||||
fml.valence = len(children)
|
||||
}
|
||||
|
||||
func (fml Formula) GetSubFormulae() []Formula {
|
||||
var n int = fml.valence
|
||||
var children = make([]Formula, n)
|
||||
for i, subfml := range fml.subformulae {
|
||||
children[i] = *subfml
|
||||
}
|
||||
return children
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
func (fml Formula) Deepcopy() Formula {
|
||||
var children = make([](*Formula), len(fml.subformulae))
|
||||
for i, child := range fml.subformulae {
|
||||
childCopy := child.Deepcopy()
|
||||
children[i] = &childCopy
|
||||
}
|
||||
return Formula{
|
||||
expr: fml.expr,
|
||||
kind: fml.kind,
|
||||
valence: fml.valence,
|
||||
subformulae: children,
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
|
||||
* METHODS: Basic constructions
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
var Tautology = Formula{
|
||||
kind: "taut",
|
||||
expr: "1",
|
||||
valence: 0,
|
||||
subformulae: [](*Formula){},
|
||||
}
|
||||
|
||||
var Contradiction = Formula{
|
||||
kind: "contradiction",
|
||||
expr: "0",
|
||||
valence: 0,
|
||||
subformulae: [](*Formula){},
|
||||
}
|
||||
|
||||
func Atom(expr string) Formula {
|
||||
return Formula{
|
||||
kind: "atom",
|
||||
expr: expr,
|
||||
valence: 0,
|
||||
subformulae: [](*Formula){},
|
||||
}
|
||||
}
|
||||
|
||||
func NegatedAtom(expr string) Formula {
|
||||
return Negation(Atom(expr))
|
||||
}
|
||||
|
||||
func Generic(expr string) Formula {
|
||||
return Formula{
|
||||
kind: "generic",
|
||||
expr: expr,
|
||||
valence: 0,
|
||||
subformulae: [](*Formula){},
|
||||
}
|
||||
}
|
||||
|
||||
func Negation(fml Formula) Formula {
|
||||
return Formula{
|
||||
kind: "not",
|
||||
expr: "!" + " " + fml.expr,
|
||||
valence: 1,
|
||||
subformulae: [](*Formula){&fml},
|
||||
}
|
||||
}
|
||||
|
||||
func Conjunction2(fml1 Formula, fml2 Formula) Formula {
|
||||
return Formula{
|
||||
kind: "and2",
|
||||
expr: "(" + fml1.expr + " && " + fml2.expr + ")",
|
||||
valence: 2,
|
||||
subformulae: [](*Formula){&fml1, &fml2},
|
||||
}
|
||||
}
|
||||
|
||||
func Conjunction(fmls []Formula) Formula {
|
||||
var expr string = ""
|
||||
var children = make([](*Formula), len(fmls))
|
||||
for i, fml := range fmls {
|
||||
if i > 0 {
|
||||
expr += " && "
|
||||
}
|
||||
expr += fml.expr
|
||||
children[i] = &fml
|
||||
}
|
||||
return Formula{
|
||||
kind: "and",
|
||||
expr: "(" + expr + ")",
|
||||
valence: len(children),
|
||||
subformulae: children,
|
||||
}
|
||||
}
|
||||
|
||||
func Disjunction2(fml1 Formula, fml2 Formula) Formula {
|
||||
return Formula{
|
||||
kind: "or2",
|
||||
expr: "(" + fml1.expr + " || " + fml2.expr + ")",
|
||||
valence: 2,
|
||||
subformulae: [](*Formula){&fml1, &fml2},
|
||||
}
|
||||
}
|
||||
|
||||
func Disjunction(fmls []Formula) Formula {
|
||||
var expr string = ""
|
||||
var children = make([](*Formula), len(fmls))
|
||||
for i, fml := range fmls {
|
||||
if i > 0 {
|
||||
expr += " || "
|
||||
}
|
||||
expr += fml.expr
|
||||
children[i] = &fml
|
||||
}
|
||||
return Formula{
|
||||
kind: "or",
|
||||
expr: "(" + expr + ")",
|
||||
valence: len(children),
|
||||
subformulae: children,
|
||||
}
|
||||
}
|
||||
|
||||
func Implies(fml1 Formula, fml2 Formula) Formula {
|
||||
return Formula{
|
||||
kind: "implies",
|
||||
expr: "(" + fml1.expr + " -> " + fml2.expr + ")",
|
||||
valence: 2,
|
||||
subformulae: [](*Formula){&fml1, &fml2},
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
|
||||
* 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"
|
||||
}
|
||||
165
codego/aussagenlogik/formulae/formulae_generate.go
Normal file
165
codego/aussagenlogik/formulae/formulae_generate.go
Normal file
@@ -0,0 +1,165 @@
|
||||
package formulae
|
||||
|
||||
// NOTE: GoLang hat noch keine generics. Erst 2022.
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* Generate int-value FN from scheme
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func CreateFromSchemeIntValued(scheme func(fml Formula, prevValues []int) int) func(fml Formula) int {
|
||||
var fn func(fml Formula) int
|
||||
var subFn = func(ch chan int, subfml Formula) { ch <- fn(subfml) }
|
||||
fn = func(fml Formula) int {
|
||||
var subfmls = fml.GetSubFormulae()
|
||||
var n = len(subfmls)
|
||||
var subChan = make([](chan int), n)
|
||||
var prevValues = make([]int, len(subfmls))
|
||||
// start parallel computations on subformulas
|
||||
for i, subfml := range subfmls {
|
||||
subChan[i] = make(chan int) // create Channel, since currently nil
|
||||
go subFn(subChan[i], subfml)
|
||||
}
|
||||
// successively read values
|
||||
for i := 0; i < n; i++ {
|
||||
prevValues[i] = <-subChan[i]
|
||||
}
|
||||
// apply schema to get value for formula
|
||||
return scheme(fml, prevValues)
|
||||
}
|
||||
return fn
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* Generate string-value FN from scheme
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func CreateFromSchemeStringValued(scheme func(fml Formula, prevValues []string) string) func(fml Formula) string {
|
||||
var fn func(fml Formula) string
|
||||
var subFn = func(ch chan string, subfml Formula) { ch <- fn(subfml) }
|
||||
fn = func(fml Formula) string {
|
||||
var subfmls = fml.GetSubFormulae()
|
||||
var n = len(subfmls)
|
||||
var subChan = make([](chan string), n)
|
||||
var prevValues = make([]string, len(subfmls))
|
||||
// start parallel computations on subformulas
|
||||
for i, subfml := range subfmls {
|
||||
subChan[i] = make(chan string) // create Channel, since currently nil
|
||||
go subFn(subChan[i], subfml)
|
||||
}
|
||||
// successively read values
|
||||
for i := 0; i < n; i++ {
|
||||
prevValues[i] = <-subChan[i]
|
||||
}
|
||||
// apply schema to get value for formula
|
||||
return scheme(fml, prevValues)
|
||||
}
|
||||
return fn
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* Generate *[]string-value Fn from scheme
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func CreateFromSchemeStringsValued(scheme func(fml Formula, prevValues [][]string) []string) func(fml Formula) []string {
|
||||
var fn func(fml Formula) []string
|
||||
var subFn = func(ch chan []string, subfml Formula) { ch <- fn(subfml) }
|
||||
fn = func(fml Formula) []string {
|
||||
var subfmls = fml.GetSubFormulae()
|
||||
var n = len(subfmls)
|
||||
var subChan = make([](chan []string), n)
|
||||
var prevValues = make([][]string, len(subfmls))
|
||||
// start parallel computations on subformulas
|
||||
for i, subfml := range subfmls {
|
||||
subChan[i] = make(chan []string) // create Channel, since currently nil
|
||||
go subFn(subChan[i], subfml)
|
||||
}
|
||||
// successively read values
|
||||
for i := 0; i < n; i++ {
|
||||
prevValues[i] = <-subChan[i]
|
||||
}
|
||||
// apply schema to get value for formula
|
||||
return scheme(fml, prevValues)
|
||||
}
|
||||
return fn
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* Generate Formula-value Fn from scheme
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func CreateFromSchemeFmlValued(scheme func(fml Formula, prevValues []Formula) Formula) func(fml Formula) Formula {
|
||||
var fn func(fml Formula) Formula
|
||||
var subFn = func(ch chan Formula, subfml Formula) { ch <- fn(subfml) }
|
||||
fn = func(fml Formula) Formula {
|
||||
var subfmls = fml.GetSubFormulae()
|
||||
var n = len(subfmls)
|
||||
var subChan = make([](chan Formula), n)
|
||||
var prevValues = make([]Formula, len(subfmls))
|
||||
// start parallel computations on subformulas
|
||||
for i, subfml := range subfmls {
|
||||
subChan[i] = make(chan Formula) // create Channel, since currently nil
|
||||
go subFn(subChan[i], subfml)
|
||||
}
|
||||
// successively read values
|
||||
for i := 0; i < n; i++ {
|
||||
prevValues[i] = <-subChan[i]
|
||||
}
|
||||
// apply schema to get value for formula
|
||||
return scheme(fml, prevValues)
|
||||
}
|
||||
return fn
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* Generate *[]Formula-value Fn from scheme
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func CreateFromSchemeFmlsValued(scheme func(fml Formula, prevValues [](*[]Formula)) *[]Formula) func(fml Formula) *[]Formula {
|
||||
var fn func(fml Formula) *[]Formula
|
||||
var subFn = func(ch chan *[]Formula, subfml Formula) { ch <- fn(subfml) }
|
||||
fn = func(fml Formula) *[]Formula {
|
||||
var subfmls = fml.GetSubFormulae()
|
||||
var n = len(subfmls)
|
||||
var subChan = make([](chan *[]Formula), n)
|
||||
var prevValues = make([](*[]Formula), len(subfmls))
|
||||
// start parallel computations on subformulas
|
||||
for i, subfml := range subfmls {
|
||||
subChan[i] = make(chan *[]Formula) // create Channel, since currently nil
|
||||
go subFn(subChan[i], subfml)
|
||||
}
|
||||
// successively read values
|
||||
for i := 0; i < n; i++ {
|
||||
prevValues[i] = <-subChan[i]
|
||||
}
|
||||
// apply schema to get value for formula
|
||||
return scheme(fml, prevValues)
|
||||
}
|
||||
return fn
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* Generate {pos: Formula, ne: Formula}-value Fn from scheme
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func CreateFromSchemeFmlPairValued(scheme func(fml Formula, prevValues []FormulaPair) FormulaPair) func(fml Formula) FormulaPair {
|
||||
var fn func(fml Formula) FormulaPair
|
||||
var subFn = func(ch chan FormulaPair, subfml Formula) { ch <- fn(subfml) }
|
||||
fn = func(fml Formula) FormulaPair {
|
||||
var subfmls = fml.GetSubFormulae()
|
||||
var n = len(subfmls)
|
||||
var subChan = make([](chan FormulaPair), n)
|
||||
var prevValues = make([]FormulaPair, len(subfmls))
|
||||
// start parallel computations on subformulas
|
||||
for i, subfml := range subfmls {
|
||||
subChan[i] = make(chan FormulaPair) // create Channel, since currently nil
|
||||
go subFn(subChan[i], subfml)
|
||||
}
|
||||
// successively read values
|
||||
for i := 0; i < n; i++ {
|
||||
prevValues[i] = <-subChan[i]
|
||||
}
|
||||
// apply schema to get value for formula
|
||||
return scheme(fml, prevValues)
|
||||
}
|
||||
return fn
|
||||
}
|
||||
34
codego/aussagenlogik/formulae/formulae_types.go
Normal file
34
codego/aussagenlogik/formulae/formulae_types.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package formulae
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* TYPE FormulaPair, FormulaPairs
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
type FormulaPair struct {
|
||||
Pos Formula
|
||||
Neg Formula
|
||||
}
|
||||
|
||||
type FormulaPairs []FormulaPair
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* Methods for FormulaPairs
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func NewFormulaPairs(pairs []FormulaPair) FormulaPairs { return pairs }
|
||||
|
||||
func (pairs FormulaPairs) Pos() []Formula {
|
||||
var fmls = make([]Formula, len(pairs))
|
||||
for i, pair := range pairs {
|
||||
fmls[i] = pair.Pos
|
||||
}
|
||||
return fmls
|
||||
}
|
||||
|
||||
func (pairs FormulaPairs) Neg() []Formula {
|
||||
var fmls = make([]Formula, len(pairs))
|
||||
for i, pair := range pairs {
|
||||
fmls[i] = pair.Neg
|
||||
}
|
||||
return fmls
|
||||
}
|
||||
Reference in New Issue
Block a user