master > master: codego - auslagern, erzeugungsmethode verbessert, SyntaxBaum -> Formula

This commit is contained in:
RD
2021-05-14 16:58:27 +02:00
parent d490406892
commit 73b7817dcd
17 changed files with 1105 additions and 647 deletions

View File

@@ -0,0 +1,20 @@
package recursion
import (
"logik/aussagenlogik/formulae"
)
/* ---------------------------------------------------------------- *
* METHOD: Atoms
* ---------------------------------------------------------------- */
func Atoms(tree formulae.Formula) []string {
// Definiere Schema:
var schema = func(tree formulae.Formula, prevValues [][]string) []string {
// Herausforderung: schreibe diese Funktion!
return []string{}
}
// Erzeuge Funktion aus Schema und berechne Wert:
fn := formulae.CreateFromSchemeStringsValued(schema)
return fn(tree)
}

View File

@@ -0,0 +1,49 @@
package recursion
import (
"logik/aussagenlogik/formulae"
)
/* ---------------------------------------------------------------- *
* METHOD: Formula Depth
* ---------------------------------------------------------------- */
func FmlDepth(tree formulae.Formula) int {
// Definiere Schema:
var schema = func(tree formulae.Formula, prevValues []int) int {
// Herausforderung: schreibe diese Funktion!
return 0
}
// Erzeuge Funktion aus Schema und berechne Wert:
fn := formulae.CreateFromSchemeIntValued(schema)
return fn(tree)
}
/* ---------------------------------------------------------------- *
* METHOD: Formula Length
* ---------------------------------------------------------------- */
func FmlLength(tree formulae.Formula) int {
// Definiere Schema:
var schema = func(tree formulae.Formula, prevValues []int) int {
// Herausforderung: schreibe diese Funktion!
return 0
}
// Erzeuge Funktion aus Schema und berechne Wert:
fn := formulae.CreateFromSchemeIntValued(schema)
return fn(tree)
}
/* ---------------------------------------------------------------- *
* METHOD: Number of Parentheses
* ---------------------------------------------------------------- */
func NrParentheses(tree formulae.Formula) int {
// Definiere Schema:
var schema = func(tree formulae.Formula, prevValues []int) int {
// Herausforderung: schreibe diese Funktion!
return 0
}
// Erzeuge Funktion aus Schema und berechne Wert:
fn := formulae.CreateFromSchemeIntValued(schema)
return fn(tree)
}

View File

@@ -0,0 +1,42 @@
package recursion
import (
"logik/aussagenlogik/formulae"
"logik/core/utils"
)
/* ---------------------------------------------------------------- *
* METHOD: Evaluation of fomulae in models
* ---------------------------------------------------------------- */
func Eval(tree formulae.Formula, I []string) int {
// Definiere (parameterisiertes) Schema:
var schema = func(_I []string) func(formulae.Formula, []int) int {
return func(tree formulae.Formula, prevValues []int) int {
if tree.IsAtom() || tree.IsGeneric() {
return utils.BoolToInt(utils.StrListContains(_I, tree.GetExpr()))
} else if tree.IsTautologySymbol() {
return 1
} else if tree.IsContradictionSymbol() {
return 0
} else if tree.IsNegation() {
return 1 - prevValues[0]
} else if tree.IsConjunction2() {
return utils.Min2(prevValues[0], prevValues[1])
} else if tree.IsConjunction() {
return utils.MinList(prevValues)
} else if tree.IsDisjunction2() {
return utils.Max2(prevValues[0], prevValues[1])
} else if tree.IsDisjunction() {
return utils.MaxList(prevValues)
} else if tree.IsImplication() {
return utils.BoolToInt(prevValues[0] <= prevValues[1])
} else {
panic("Could not evaluate expression!")
}
}
}
// Erzeuge Funktion aus Schema und berechne Wert:
fn := formulae.CreateFromSchemeIntValued(schema(I))
return fn(tree)
}

View File

@@ -0,0 +1,77 @@
package recursion
import (
"logik/aussagenlogik/formulae"
)
/* ---------------------------------------------------------------- *
* METHOD: compute NNF
* ---------------------------------------------------------------- */
// NOTE: diese bedarf einer Art Doppeltrekursion
func NNF(tree formulae.Formula) formulae.Formula {
// Definiere Schema:
var schema = func(tree formulae.Formula, prevValues []formulae.FormulaPair) formulae.FormulaPair {
// separate out positive and negative parts:
var pairs = formulae.NewFormulaPairs(prevValues)
var prevPos = pairs.Pos()
var prevNeg = pairs.Neg()
// compute value from previous positive/negative parts:
if tree.IsPositiveLiteral() {
return formulae.FormulaPair{
Pos: tree.Deepcopy(),
Neg: formulae.Negation(tree),
}
} else if tree.IsNegativeLiteral() {
return formulae.FormulaPair{
Pos: tree.Deepcopy(),
Neg: prevPos[0],
}
} else if tree.IsTautologySymbol() {
return formulae.FormulaPair{
Pos: formulae.Tautology,
Neg: formulae.Contradiction,
}
} else if tree.IsContradictionSymbol() {
return formulae.FormulaPair{
Pos: formulae.Contradiction,
Neg: formulae.Tautology,
}
} else if tree.IsNegation() {
return formulae.FormulaPair{
Pos: prevNeg[0],
Neg: prevPos[0],
}
} else if tree.IsConjunction2() {
return formulae.FormulaPair{
Pos: formulae.Conjunction2(prevPos[0], prevPos[1]),
Neg: formulae.Disjunction2(prevNeg[0], prevNeg[1]),
}
} else if tree.IsConjunction() {
return formulae.FormulaPair{
Pos: formulae.Conjunction(prevPos),
Neg: formulae.Disjunction(prevNeg),
}
} else if tree.IsDisjunction2() {
return formulae.FormulaPair{
Pos: formulae.Disjunction2(prevPos[0], prevPos[1]),
Neg: formulae.Conjunction2(prevNeg[0], prevNeg[1]),
}
} else if tree.IsDisjunction() {
return formulae.FormulaPair{
Pos: formulae.Disjunction(prevPos),
Neg: formulae.Conjunction(prevNeg),
}
} else if tree.IsImplication() {
return formulae.FormulaPair{
Pos: formulae.Implies(prevPos[0], prevPos[1]),
Neg: formulae.Conjunction2(prevPos[0], prevNeg[1]),
}
} else {
panic("Could not evaluate expression!")
}
}
// Erzeuge Funktion aus Schema und berechne Wert:
fn := formulae.CreateFromSchemeFmlPairValued(schema)
return fn(tree).Pos
}

View File

@@ -0,0 +1,359 @@
package recursion_test
/* ---------------------------------------------------------------- *
* UNIT TESTING
* ---------------------------------------------------------------- */
import (
"logik/aussagenlogik/formulae"
"logik/aussagenlogik/recursion"
"logik/aussagenlogik/schema"
"logik/core/utils"
"testing"
"github.com/stretchr/testify/assert"
)
/* ---------------------------------------------------------------- *
* TESTCASE eval(·, ·)
* ---------------------------------------------------------------- */
func TestEvalLiteral(test *testing.T) {
var assert = assert.New(test)
var val int
var fml formulae.Formula
var I []string
fml = schema.ParseExpr("A0")
I = []string{"A0"}
val = recursion.Eval(fml, I)
assert.Equal(1, val)
fml = schema.ParseExpr("A0")
I = []string{}
val = recursion.Eval(fml, I)
assert.Equal(0, val)
fml = schema.ParseExpr("! A0")
I = []string{"A0"}
val = recursion.Eval(fml, I)
assert.Equal(0, val)
fml = schema.ParseExpr("! A0")
I = []string{}
val = recursion.Eval(fml, I)
assert.Equal(1, val)
}
func TestEvalComplex1(test *testing.T) {
var assert = assert.New(test)
var val int
var fml formulae.Formula
var I []string
fml = schema.ParseExpr("( ! A0 || (( A0 && A3 ) || A2 ))")
I = []string{"A0", "A2"}
val = recursion.Eval(fml, I)
assert.Equal(1, val)
I = []string{"A0", "A3"}
val = recursion.Eval(fml, I)
assert.Equal(1, val)
I = []string{"A0"}
val = recursion.Eval(fml, I)
assert.Equal(0, val)
I = []string{"A4", "A8"}
val = recursion.Eval(fml, I)
assert.Equal(1, val)
}
func TestEvalComplex2(test *testing.T) {
var assert = assert.New(test)
var val int
var fml formulae.Formula
var I []string
fml = schema.ParseExpr("( ! A0 || (( A0 && A3 ) || ! A2 ))")
I = []string{"A0", "A2"}
val = recursion.Eval(fml, I)
assert.Equal(0, val)
I = []string{"A0", "A3"}
val = recursion.Eval(fml, I)
assert.Equal(1, val)
}
/* ---------------------------------------------------------------- *
* TESTCASE Atoms(·)
* ---------------------------------------------------------------- */
func TestAtomsNoduplicates(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var fml formulae.Formula
var val []string
fml = schema.ParseExpr("( A4 && ( A4 || A4 ))")
val = recursion.Atoms(fml)
var n int = len(utils.FilterStrings(&val, func(x string) bool { return x == "A4" }))
assert.Equal(1, n, "Atome dürfen nicht mehrfach vorkommen!")
}
func TestAtomsNononatoms(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
test.Skip("Syntax for generic expressions in ANTLR4 g4 needs to be implemented.")
var assert = assert.New(test)
var fml formulae.Formula
var val []string
fml = schema.ParseExpr("( {F} || A3 )")
val = recursion.Atoms(fml)
utils.SortStrings(&val)
assert.NotContains(val, "F", "Nichtatomare Formeln dürfen nicht vorkommen!")
}
func TestAtomsCalc1(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var fml formulae.Formula
var val []string
fml = schema.ParseExpr("A0")
val = recursion.Atoms(fml)
utils.SortStrings(&val)
assert.Equal([]string{"A0"}, val)
}
func TestAtomsCalc2(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var fml formulae.Formula
var val []string
fml = schema.ParseExpr("((( ! A8 && A3 ) || A4 ) && A0 )")
val = recursion.Atoms(fml)
utils.SortStrings(&val)
assert.Equal([]string{"A0", "A3", "A4", "A8"}, val)
}
/* ---------------------------------------------------------------- *
* TESTCASE depth(·, ·)
* ---------------------------------------------------------------- */
func TestDepthCalc1(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("A0")
val = recursion.FmlDepth(fml)
assert.Equal(0, val)
}
func TestDepthCalc2(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("!! A8")
val = recursion.FmlDepth(fml)
assert.Equal(2, val)
}
func TestDepthCalc3(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("( ! A0 && A3 )")
val = recursion.FmlDepth(fml)
assert.Equal(2, val)
}
func TestDepthCalc4(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
val = recursion.FmlDepth(fml)
assert.Equal(4, val)
}
func TestDepthCalc5(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
val = recursion.FmlDepth(fml)
assert.Equal(5, val)
}
/* ---------------------------------------------------------------- *
* TESTCASE length(·)
* ---------------------------------------------------------------- */
func TestLengthCalc1(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("A0")
val = recursion.FmlLength(fml)
assert.Equal(1, val)
}
func TestLengthCalc2(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("!! A8")
val = recursion.FmlLength(fml)
assert.Equal(3, val)
}
func TestLengthCalc3(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("( ! A0 && A3 )")
val = recursion.FmlLength(fml)
assert.Equal(4, val)
}
func TestLengthCalc4(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
val = recursion.FmlLength(fml)
assert.Equal(8, val)
}
func TestLengthCalc5(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
val = recursion.FmlLength(fml)
assert.Equal(9, val)
}
/* ---------------------------------------------------------------- *
* TESTCASE #Parentheses(·)
* ---------------------------------------------------------------- */
func TestParenthesesCalc1(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("A0")
val = recursion.NrParentheses(fml)
assert.Equal(0, val)
}
func TestParenthesesCalc2(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("!! A8")
val = recursion.NrParentheses(fml)
assert.Equal(0, val)
}
func TestParenthesesCalc3(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("( ! A0 && A3 )")
val = recursion.NrParentheses(fml)
assert.Equal(2, val)
}
func TestParenthesesCalc4(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
val = recursion.NrParentheses(fml)
assert.Equal(6, val)
}
func TestParenthesesCalc5(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var val int
var fml formulae.Formula
fml = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
val = recursion.NrParentheses(fml)
assert.Equal(6, val)
}
/* ---------------------------------------------------------------- *
* TESTCASE NNF
* ---------------------------------------------------------------- */
func TestNNFatoms(test *testing.T) {
var assert = assert.New(test)
var fml formulae.Formula
var nnf_expected formulae.Formula
nnf_expected = formulae.Atom("A7")
fml = schema.ParseExpr("A7")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
fml = schema.ParseExpr("!! A7")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
nnf_expected = formulae.NegatedAtom("A7")
fml = schema.ParseExpr("! A7")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
fml = schema.ParseExpr("!!! A7")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
}
func TestNNFconj(test *testing.T) {
var assert = assert.New(test)
var fml formulae.Formula
var nnf_expected formulae.Formula
nnf_expected = formulae.Disjunction2(formulae.NegatedAtom("A0"), formulae.NegatedAtom("A1"))
fml = schema.ParseExpr("! (A0 && A1)")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
nnf_expected = formulae.Disjunction2(formulae.Atom("A0"), formulae.Atom("A1"))
fml = schema.ParseExpr("! (! A0 && ! A1)")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
nnf_expected = formulae.Conjunction2(formulae.Atom("A0"), formulae.NegatedAtom("A1"))
fml = schema.ParseExpr("(A0 && ! A1)")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
}
func TestNNFdisj(test *testing.T) {
var assert = assert.New(test)
var fml formulae.Formula
var nnf_expected formulae.Formula
nnf_expected = formulae.Conjunction2(formulae.NegatedAtom("A0"), formulae.NegatedAtom("A1"))
fml = schema.ParseExpr("! (A0 || A1)")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
nnf_expected = formulae.Conjunction2(formulae.Atom("A0"), formulae.Atom("A1"))
fml = schema.ParseExpr("! (! A0 || ! A1)")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
nnf_expected = formulae.Disjunction2(formulae.Atom("A0"), formulae.NegatedAtom("A1"))
fml = schema.ParseExpr("(A0 || ! A1)")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
}
func TestNNFcalcComplex(test *testing.T) {
var assert = assert.New(test)
var fml formulae.Formula
var nnf_expected formulae.Formula
fml = schema.ParseExpr("! (! (!A0 || A1) || ! ! A8)")
nnf_expected = schema.ParseExpr("((!A0 || A1) && ! A8)")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
fml = schema.ParseExpr("! (! (!A0 || !(A1 && ! A7)) && ! A8)")
nnf_expected = schema.ParseExpr("((!A0 || (! A1 || A7)) || A8)")
assert.Equal(nnf_expected.GetExpr(), recursion.NNF(fml).GetExpr())
}