Compare commits

...

7 Commits

10 changed files with 426 additions and 253 deletions

View File

@ -1,7 +1,6 @@
package rekursion
import (
"log"
"logik/aussagenlogik/syntaxbaum"
"logik/core/utils"
)
@ -10,72 +9,62 @@ import (
* EXPORTS
* ---------------------------------------------------------------- */
func RekursivEval(tree syntaxbaum.SyntaxBaum, I []string) int {
var children = tree.GetChildren()
type RekursiveChannelInt struct {
channel chan int
}
func RekursivEval(ch chan int, tree syntaxbaum.SyntaxBaum, I []string) {
// Werte für Teilformeln rekursiv berechnen
fn := func(_ch chan int, _tree syntaxbaum.SyntaxBaum) { RekursivEval(_ch, _tree, I) }
var values = RekursiveCallInt(fn, tree.GetChildren())
// Aus Werten für Teilformeln Wert für Formeln berechnen
if tree.IsAtom() || tree.IsGeneric() {
if utils.StrListContains(I, tree.Expr) {
return 1
}
return 0
ch <- utils.BoolToInt(utils.StrListContains(I, tree.GetExpr()))
} else if tree.IsTautologySymbol() {
return 1
ch <- 1
} else if tree.IsContradictionSymbol() {
return 0
ch <- 0
} else if tree.IsNegation() {
subtree0, _ := tree.GetChild()
val0 := RekursivEval(subtree0, I)
return 1 - val0
ch <- 1 - values[0]
} else if tree.IsConjunction2() {
val0 := RekursivEval(children[0], I)
val1 := RekursivEval(children[1], I)
return utils.Min2(val0, val1)
ch <- utils.Min2(values[0], values[1])
} else if tree.IsConjunction() {
var val = 1
for _, subtree := range children {
var val_ = RekursivEval(subtree, I)
val = utils.Min2(val, val_)
}
return val
ch <- utils.MinList(values)
} else if tree.IsDisjunction2() {
val0 := RekursivEval(children[0], I)
val1 := RekursivEval(children[1], I)
return utils.Max2(val0, val1)
ch <- utils.Max2(values[0], values[1])
} else if tree.IsDisjunction() {
var val = 0
for _, subtree := range children {
var val_ = RekursivEval(subtree, I)
val = utils.Max2(val, val_)
}
return val
ch <- utils.MaxList(values)
} else if tree.IsImplication() {
val0 := RekursivEval(children[0], I)
val1 := RekursivEval(children[1], I)
if val0 <= val1 {
return 1
}
return 0
ch <- utils.BoolToInt(values[0] <= values[1])
} else {
log.Fatal("Could not evaluate expression!")
return 0
panic("Could not evaluate expression!")
}
}
func RekursivAtoms(tree syntaxbaum.SyntaxBaum) []string {
func RekursivAtoms(ch chan []string, tree syntaxbaum.SyntaxBaum) {
// // Werte für Teilformeln rekursiv berechnen
// var values = RekursiveCallStringList(RekursivAtoms, tree.GetChildren())
// Herausforderung: schreibe diese Funktion!
return []string{}
ch <- []string{}
}
func RekursivDepth(tree syntaxbaum.SyntaxBaum) int {
func RekursivDepth(ch chan int, tree syntaxbaum.SyntaxBaum) {
// // Werte für Teilformeln rekursiv berechnen
// var values = RekursiveCallInt(RekursivDepth, tree.GetChildren())
// Herausforderung: schreibe diese Funktion!
return 0
ch <- 0
}
func RekursivLength(tree syntaxbaum.SyntaxBaum) int {
func RekursivLength(ch chan int, tree syntaxbaum.SyntaxBaum) {
// // Werte für Teilformeln rekursiv berechnen
// var values = RekursiveCallInt(RekursivLength, tree.GetChildren())
// Herausforderung: schreibe diese Funktion!
return 0
ch <- 0
}
func RekursivParentheses(tree syntaxbaum.SyntaxBaum) int {
func RekursivParentheses(ch chan int, tree syntaxbaum.SyntaxBaum) {
// // Werte für Teilformeln rekursiv berechnen
// var values = RekursiveCallInt(RekursivParentheses, tree.GetChildren())
// Herausforderung: schreibe diese Funktion!
return 0
ch <- 0
}

View File

@ -0,0 +1,51 @@
package rekursion
import (
"logik/aussagenlogik/syntaxbaum"
)
/* ---------------------------------------------------------------- *
* EXPORTS
* ---------------------------------------------------------------- */
func RekursiveCallInt(fn func(ch chan int, tree syntaxbaum.SyntaxBaum), children []syntaxbaum.SyntaxBaum) []int {
subChannel := make(chan int)
values := make([]int, len(children))
// start parallel computations on subformulae
for _, subtree := range children {
go fn(subChannel, subtree)
}
// successively read values
for i := 0; i < len(children); i++ {
values[i] = <-subChannel
}
return values
}
func RekursiveCallString(fn func(ch chan string, tree syntaxbaum.SyntaxBaum), children []syntaxbaum.SyntaxBaum) []string {
subChannel := make(chan string)
values := make([]string, len(children))
// start parallel computations
for _, subtree := range children {
go fn(subChannel, subtree)
}
// successively read values
for i := 0; i < len(children); i++ {
values[i] = <-subChannel
}
return values
}
func RekursiveCallStringList(fn func(ch chan []string, tree syntaxbaum.SyntaxBaum), children []syntaxbaum.SyntaxBaum) [][]string {
subChannel := make(chan []string)
values := make([][]string, len(children))
// start parallel computations
for _, subtree := range children {
go fn(subChannel, subtree)
}
// successively read values
for i := 0; i < len(children); i++ {
values[i] = <-subChannel
}
return values
}

View File

@ -20,59 +20,59 @@ import (
func TestRekursivEvalLiteral(test *testing.T) {
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var I []string
var val int
tree, _ = schema.ParseExpr("A0")
tree = schema.ParseExpr("A0")
I = []string{"A0"}
val = rekursion.RekursivEval(tree, I)
assert.Equal(val, 1)
tree, _ = schema.ParseExpr("A0")
go rekursion.RekursivEval(ch, tree, I)
assert.Equal(<-ch, 1)
tree = schema.ParseExpr("A0")
I = []string{}
val = rekursion.RekursivEval(tree, I)
assert.Equal(val, 0)
tree, _ = schema.ParseExpr("! A0")
go rekursion.RekursivEval(ch, tree, I)
assert.Equal(<-ch, 0)
tree = schema.ParseExpr("! A0")
I = []string{"A0"}
val = rekursion.RekursivEval(tree, I)
assert.Equal(val, 0)
tree, _ = schema.ParseExpr("! A0")
go rekursion.RekursivEval(ch, tree, I)
assert.Equal(<-ch, 0)
tree = schema.ParseExpr("! A0")
I = []string{}
val = rekursion.RekursivEval(tree, I)
assert.Equal(val, 1)
go rekursion.RekursivEval(ch, tree, I)
assert.Equal(<-ch, 1)
}
func TestRekursivEvalComplex1(test *testing.T) {
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var I []string
var val int
tree, _ = schema.ParseExpr("( ! A0 || (( A0 && A3 ) || A2 ))")
tree = schema.ParseExpr("( ! A0 || (( A0 && A3 ) || A2 ))")
I = []string{"A0", "A2"}
val = rekursion.RekursivEval(tree, I)
assert.Equal(val, 1)
go rekursion.RekursivEval(ch, tree, I)
assert.Equal(<-ch, 1)
I = []string{"A0", "A3"}
val = rekursion.RekursivEval(tree, I)
assert.Equal(val, 1)
go rekursion.RekursivEval(ch, tree, I)
assert.Equal(<-ch, 1)
I = []string{"A0"}
val = rekursion.RekursivEval(tree, I)
assert.Equal(val, 0)
go rekursion.RekursivEval(ch, tree, I)
assert.Equal(<-ch, 0)
I = []string{"A4", "A8"}
val = rekursion.RekursivEval(tree, I)
assert.Equal(val, 1)
go rekursion.RekursivEval(ch, tree, I)
assert.Equal(<-ch, 1)
}
func TestRekursivEvalComplex2(test *testing.T) {
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var I []string
var val int
tree, _ = schema.ParseExpr("( ! A0 || (( A0 && A3 ) || ! A2 ))")
tree = schema.ParseExpr("( ! A0 || (( A0 && A3 ) || ! A2 ))")
I = []string{"A0", "A2"}
val = rekursion.RekursivEval(tree, I)
assert.Equal(val, 0)
go rekursion.RekursivEval(ch, tree, I)
assert.Equal(<-ch, 0)
I = []string{"A0", "A3"}
val = rekursion.RekursivEval(tree, I)
assert.Equal(val, 1)
go rekursion.RekursivEval(ch, tree, I)
assert.Equal(<-ch, 1)
}
/* ---------------------------------------------------------------- *
@ -82,10 +82,12 @@ func TestRekursivEvalComplex2(test *testing.T) {
func TestRekursivAtomsNoduplicates(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan []string)
var tree syntaxbaum.SyntaxBaum
var val []string
tree, _ = schema.ParseExpr("( A4 && ( A4 || A4 ))")
val = rekursion.RekursivAtoms(tree)
tree = schema.ParseExpr("( A4 && ( A4 || A4 ))")
go rekursion.RekursivAtoms(ch, tree)
val = <-ch
var n int = len(utils.FilterStrings(&val, func(x string) bool { return x == "A4" }))
assert.Equal(n, 1, "Atome dürfen nicht mehrfach vorkommen!")
}
@ -94,10 +96,12 @@ func TestRekursivAtomsNononatoms(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 ch = make(chan []string)
var tree syntaxbaum.SyntaxBaum
var val []string
tree, _ = schema.ParseExpr("( {F} || A3 )")
val = rekursion.RekursivAtoms(tree)
tree = schema.ParseExpr("( {F} || A3 )")
go rekursion.RekursivAtoms(ch, tree)
val = <-ch
utils.SortStrings(&val)
assert.NotContains(val, "F", "Nichtatomare Formeln dürfen nicht vorkommen!")
}
@ -105,10 +109,12 @@ func TestRekursivAtomsNononatoms(test *testing.T) {
func TestRekursivAtomsCalc1(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan []string)
var tree syntaxbaum.SyntaxBaum
var val []string
tree, _ = schema.ParseExpr("A0")
val = rekursion.RekursivAtoms(tree)
tree = schema.ParseExpr("A0")
go rekursion.RekursivAtoms(ch, tree)
val = <-ch
utils.SortStrings(&val)
assert.Equal(val, []string{"A0"})
}
@ -116,10 +122,12 @@ func TestRekursivAtomsCalc1(test *testing.T) {
func TestRekursivAtomsCalc2(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan []string)
var tree syntaxbaum.SyntaxBaum
var val []string
tree, _ = schema.ParseExpr("((( ! A8 && A3 ) || A4 ) && A0 )")
val = rekursion.RekursivAtoms(tree)
tree = schema.ParseExpr("((( ! A8 && A3 ) || A4 ) && A0 )")
go rekursion.RekursivAtoms(ch, tree)
val = <-ch
utils.SortStrings(&val)
assert.Equal(val, []string{"A0", "A3", "A4", "A8"})
}
@ -131,51 +139,51 @@ func TestRekursivAtomsCalc2(test *testing.T) {
func TestRekursivDepthCalc1(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("A0")
val = rekursion.RekursivDepth(tree)
assert.Equal(val, 0)
tree = schema.ParseExpr("A0")
go rekursion.RekursivDepth(ch, tree)
assert.Equal(<-ch, 0)
}
func TestRekursivDepthCalc2(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("!! A8")
val = rekursion.RekursivDepth(tree)
assert.Equal(val, 2)
tree = schema.ParseExpr("!! A8")
go rekursion.RekursivDepth(ch, tree)
assert.Equal(<-ch, 2)
}
func TestRekursivDepthCalc3(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("( ! A0 && A3 )")
val = rekursion.RekursivDepth(tree)
assert.Equal(val, 2)
tree = schema.ParseExpr("( ! A0 && A3 )")
go rekursion.RekursivDepth(ch, tree)
assert.Equal(<-ch, 2)
}
func TestRekursivDepthCalc4(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
val = rekursion.RekursivDepth(tree)
assert.Equal(val, 4)
tree = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
go rekursion.RekursivDepth(ch, tree)
assert.Equal(<-ch, 4)
}
func TestRekursivDepthCalc5(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
val = rekursion.RekursivDepth(tree)
assert.Equal(val, 5)
tree = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
go rekursion.RekursivDepth(ch, tree)
assert.Equal(<-ch, 5)
}
/* ---------------------------------------------------------------- *
@ -185,51 +193,51 @@ func TestRekursivDepthCalc5(test *testing.T) {
func TestRekursivLengthCalc1(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("A0")
val = rekursion.RekursivLength(tree)
assert.Equal(val, 1)
tree = schema.ParseExpr("A0")
go rekursion.RekursivLength(ch, tree)
assert.Equal(<-ch, 1)
}
func TestRekursivLengthCalc2(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("!! A8")
val = rekursion.RekursivLength(tree)
assert.Equal(val, 3)
tree = schema.ParseExpr("!! A8")
go rekursion.RekursivLength(ch, tree)
assert.Equal(<-ch, 3)
}
func TestRekursivLengthCalc3(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("( ! A0 && A3 )")
val = rekursion.RekursivLength(tree)
assert.Equal(val, 4)
tree = schema.ParseExpr("( ! A0 && A3 )")
go rekursion.RekursivLength(ch, tree)
assert.Equal(<-ch, 4)
}
func TestRekursivLengthCalc4(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
val = rekursion.RekursivLength(tree)
assert.Equal(val, 8)
tree = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
go rekursion.RekursivLength(ch, tree)
assert.Equal(<-ch, 8)
}
func TestRekursivLengthCalc5(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
val = rekursion.RekursivLength(tree)
assert.Equal(val, 9)
tree = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
go rekursion.RekursivLength(ch, tree)
assert.Equal(<-ch, 9)
}
/* ---------------------------------------------------------------- *
@ -239,49 +247,49 @@ func TestRekursivLengthCalc5(test *testing.T) {
func TestRekursivParenthesesCalc1(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("A0")
val = rekursion.RekursivParentheses(tree)
assert.Equal(val, 0)
tree = schema.ParseExpr("A0")
go rekursion.RekursivParentheses(ch, tree)
assert.Equal(<-ch, 0)
}
func TestRekursivParenthesesCalc2(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("!! A8")
val = rekursion.RekursivParentheses(tree)
assert.Equal(val, 0)
tree = schema.ParseExpr("!! A8")
go rekursion.RekursivParentheses(ch, tree)
assert.Equal(<-ch, 0)
}
func TestRekursivParenthesesCalc3(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("( ! A0 && A3 )")
val = rekursion.RekursivParentheses(tree)
assert.Equal(val, 2)
tree = schema.ParseExpr("( ! A0 && A3 )")
go rekursion.RekursivParentheses(ch, tree)
assert.Equal(<-ch, 2)
}
func TestRekursivParenthesesCalc4(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
val = rekursion.RekursivParentheses(tree)
assert.Equal(val, 6)
tree = schema.ParseExpr("((( ! A0 && A3 ) || A4 ) && A8 )")
go rekursion.RekursivParentheses(ch, tree)
assert.Equal(<-ch, 6)
}
func TestRekursivParenthesesCalc5(test *testing.T) {
test.Skip("Methode noch nicht implementiert")
var assert = assert.New(test)
var ch = make(chan int)
var tree syntaxbaum.SyntaxBaum
var val int
tree, _ = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
val = rekursion.RekursivParentheses(tree)
assert.Equal(val, 6)
tree = schema.ParseExpr("! ((( ! A0 && A3 ) || A4 ) && A8 )")
go rekursion.RekursivParentheses(ch, tree)
assert.Equal(<-ch, 6)
}

View File

@ -1,7 +1,6 @@
package schema
import (
"errors"
"logik/aussagenlogik/syntaxbaum"
parser "logik/grammars/aussagenlogik"
"strings"
@ -13,13 +12,13 @@ import (
* EXPORTS
* ---------------------------------------------------------------- */
func ParseExpr(u string) (syntaxbaum.SyntaxBaum, error) {
func ParseExpr(u string) syntaxbaum.SyntaxBaum {
var lexer = createLexer(u)
var tokenStream = lexerToTokenStream(lexer)
var prs = parser.NewaussagenlogikParser(tokenStream)
var t = prs.Start()
tree, err := createSyntaxBaum(t, prs)
return tree, err
tree := createSyntaxBaum(t, prs)
return tree
}
/* ---------------------------------------------------------------- *
@ -39,7 +38,7 @@ func createLexer(u string) antlr.Lexer {
return parser.NewaussagenlogikLexer(stream)
}
func createSyntaxBaum(tree antlr.Tree, parser antlr.Parser) (syntaxbaum.SyntaxBaum, error) {
func createSyntaxBaum(tree antlr.Tree, parser antlr.Parser) syntaxbaum.SyntaxBaum {
var ant = antlrTree{tree: tree, parser: &parser}
return ant.toSyntaxBaum()
}
@ -87,9 +86,8 @@ func (ant antlrTree) getTextContentLeaves() string {
return expr
}
func (ant antlrTree) toSyntaxBaum() (syntaxbaum.SyntaxBaum, error) {
func (ant antlrTree) toSyntaxBaum() syntaxbaum.SyntaxBaum {
var tree syntaxbaum.SyntaxBaum
var err error
var label string = ant.getLabel()
var subants = ant.getChildren()
var nChildren = len(subants)
@ -114,21 +112,20 @@ func (ant antlrTree) toSyntaxBaum() (syntaxbaum.SyntaxBaum, error) {
if nChildren == 1 {
subant := subants[0]
tree = syntaxbaum.SyntaxBaum{}
tree.Expr = subant.getTextContentLeaves()
tree.Kind = subant.getLabel()
tree.Children = [](*syntaxbaum.SyntaxBaum){}
tree.Valence = 0
return tree, nil
tree.SetKind(subant.getLabel())
tree.SetExpr(subant.getTextContentLeaves())
tree.SetChildren([](*syntaxbaum.SyntaxBaum){})
return tree
}
case "not":
if nChildren == 2 { // Children: [NotSymbol, Teilformel]
subtree, err := subants[1].toSyntaxBaum()
if nChildren == 2 {
// NOTE: Children = [NotSymbol, Teilformel]
subtree := subants[1].toSyntaxBaum()
tree = syntaxbaum.SyntaxBaum{}
tree.Expr = subants[0].getTextContent() + " " + subtree.Expr
tree.Kind = label
tree.Children = [](*syntaxbaum.SyntaxBaum){&subtree}
tree.Valence = 1
return tree, err
tree.SetKind(label)
tree.SetExpr(subants[0].getTextContent() + " " + subtree.GetExpr())
tree.SetChildren([](*syntaxbaum.SyntaxBaum){&subtree})
return tree
}
case "and2", "and", "or2", "or", "implies":
var n int = int((len(subants) + 1) / 2)
@ -139,37 +136,26 @@ func (ant antlrTree) toSyntaxBaum() (syntaxbaum.SyntaxBaum, error) {
var expr string = ""
for _, subant := range subants {
if isSymb {
expr += " " + subant.getTextContent() + " "
expr += " " + subant.getTextContent()
} else {
subtree, err_ := subant.toSyntaxBaum()
if err_ != nil {
err = err_
}
subtree := subant.toSyntaxBaum()
subtrees[i] = &subtree
expr += " " + subtree.Expr + " "
expr += " " + subtree.GetExpr()
i++
}
// NOTE: infix notation: alternatives between expression and symbol
isSymb = !isSymb
}
expr = strings.Trim(expr, " ")
var lbrace string = "("
var rbrace string = ")"
// var lbrace string = "( "
// var rbrace string = " )"
// if strings.HasPrefix(expr, "(") {
// lbrace = "("
// }
// if strings.HasSuffix(expr, ")") {
// rbrace = ")"
// }
tree = syntaxbaum.SyntaxBaum{}
tree.Expr = lbrace + expr + rbrace
tree.Kind = label
tree.Children = subtrees
tree.Valence = n
return tree, err
tree.SetKind(label)
tree.SetExpr(lbrace + expr + rbrace)
tree.SetChildren(subtrees)
return tree
}
}
return tree, errors.New("Could not parse expression")
panic("Could not parse expression")
}

View File

@ -6,6 +6,7 @@ package schema_test
import (
"logik/aussagenlogik/schema"
"logik/aussagenlogik/syntaxbaum"
"testing"
"github.com/stretchr/testify/assert"
@ -17,6 +18,25 @@ import (
func TestParseExpr(test *testing.T) {
var assert = assert.New(test)
assert.Equal(0, 0)
schema.ParseExpr("A0")
var tree syntaxbaum.SyntaxBaum
tree = schema.ParseExpr("A8712")
assert.Equal("A8712", tree.GetExpr())
assert.Equal("atom", tree.GetKind())
assert.Equal(0, len(tree.GetChildren()))
tree = schema.ParseExpr(" ! A5 ")
assert.Equal("! A5", tree.GetExpr())
assert.Equal("not", tree.GetKind())
assert.Equal(1, len(tree.GetChildren()))
tree = schema.ParseExpr("A0 -> A1")
assert.Equal("(A0 -> A1)", tree.GetExpr())
assert.Equal("implies", tree.GetKind())
assert.Equal(2, len(tree.GetChildren()))
tree = schema.ParseExpr("( A0 && A1) || A2")
assert.Equal("((A0 && A1) || A2)", tree.GetExpr())
assert.Equal("or2", tree.GetKind())
assert.Equal(2, len(tree.GetChildren()))
}

View File

@ -7,20 +7,40 @@ import (
)
type SyntaxBaum struct {
Kind string
Expr string
Valence int
Children [](*SyntaxBaum)
kind string
expr string
valence int
children [](*SyntaxBaum)
}
/* ---------------------------------------------------------------- *
* METHODS
* ---------------------------------------------------------------- */
func (tree *SyntaxBaum) SetKind(kind string) {
tree.kind = kind
}
func (tree SyntaxBaum) GetKind() string {
return tree.kind
}
func (tree *SyntaxBaum) SetExpr(expr string) {
tree.expr = expr
}
func (tree SyntaxBaum) GetExpr() string {
return tree.expr
}
func (tree *SyntaxBaum) SetChildren(children [](*SyntaxBaum)) {
tree.children = children
tree.valence = len(children)
}
func (tree SyntaxBaum) GetChildren() []SyntaxBaum {
var n int = tree.Valence
var n int = tree.valence
var children = make([]SyntaxBaum, n)
for i, subtreePtr := range tree.Children {
for i, subtreePtr := range tree.children {
children[i] = *subtreePtr
}
return children
@ -33,8 +53,8 @@ func (tree SyntaxBaum) GetChild(indexOpt ...int) (SyntaxBaum, error) {
}
var subtree SyntaxBaum
var err error
if 0 <= index && index < tree.Valence {
subtree = *(tree.Children[index])
if 0 <= index && index < tree.valence {
subtree = *(tree.children[index])
} else {
err = errors.New(fmt.Sprintf("Instance has no child of index %d !", index))
}
@ -51,18 +71,18 @@ func (tree SyntaxBaum) Pretty(preindentOpt ...string) string {
func (tree SyntaxBaum) pretty(preindent string, tab string, prepend string, depth int) string {
var indent string = preindent + strings.Repeat(tab, depth)
switch tree.Valence {
switch tree.valence {
case 0:
switch kind := tree.Kind; kind {
switch kind := tree.kind; kind {
case "atom", "generic":
return indent + prepend + kind + " " + tree.Expr
return indent + prepend + kind + " " + tree.expr
default:
return indent + prepend + kind
}
default:
var lines string = indent + prepend + tree.Kind
var lines string = indent + prepend + tree.kind
prepend = "|__ "
for _, subtree := range tree.Children {
for _, subtree := range tree.children {
lines += "\n" + subtree.pretty(preindent, tab, prepend, depth+1)
}
return lines
@ -74,11 +94,11 @@ func (tree SyntaxBaum) pretty(preindent string, tab string, prepend string, dept
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
func (tree SyntaxBaum) IsIrreducible() bool {
return tree.Valence == 0
return tree.valence == 0
}
func (tree SyntaxBaum) IsAtom() bool {
return tree.Kind == "atom"
return tree.kind == "atom"
}
func (tree SyntaxBaum) IsLiteral() bool {
@ -94,41 +114,41 @@ func (tree SyntaxBaum) IsLiteral() bool {
}
func (tree SyntaxBaum) IsGeneric() bool {
return tree.Kind == "generic"
return tree.kind == "generic"
}
func (tree SyntaxBaum) IsTautologySymbol() bool {
return tree.Kind == "taut"
return tree.kind == "taut"
}
func (tree SyntaxBaum) IsContradictionSymbol() bool {
return tree.Kind == "contradiction"
return tree.kind == "contradiction"
}
func (tree SyntaxBaum) IsConnective() bool {
return tree.Valence > 0
return tree.valence > 0
}
func (tree SyntaxBaum) IsNegation() bool {
return tree.Kind == "not"
return tree.kind == "not"
}
func (tree SyntaxBaum) IsConjunction2() bool {
return tree.Kind == "and2"
return tree.kind == "and2"
}
func (tree SyntaxBaum) IsConjunction() bool {
return tree.Kind == "and" || tree.Kind == "and2"
return tree.kind == "and" || tree.kind == "and2"
}
func (tree SyntaxBaum) IsDisjunction2() bool {
return tree.Kind == "or2"
return tree.kind == "or2"
}
func (tree SyntaxBaum) IsDisjunction() bool {
return tree.Kind == "or" || tree.Kind == "or2"
return tree.kind == "or" || tree.kind == "or2"
}
func (tree SyntaxBaum) IsImplication() bool {
return tree.Kind == "implies"
return tree.kind == "implies"
}

View File

@ -1,23 +1,39 @@
package utils
import (
"encoding/json"
"log"
"sort"
"strings"
)
/* ---------------------------------------------------------------- *
* EXPORTS
* METHODS: json
* ---------------------------------------------------------------- */
func StrListContains(list []string, x string) bool {
for _, obj := range list {
if obj == x {
return true
}
func JsonToArrayOfStrings(s string, value *[]string) {
var err error
err = json.Unmarshal([]byte(s), &value)
if err != nil {
panic(err)
}
return false
}
/* ---------------------------------------------------------------- *
* METHODS: conversion
* ---------------------------------------------------------------- */
func BoolToInt(cond bool) int {
if cond {
return 1
}
return 0
}
/* ---------------------------------------------------------------- *
* METHODS: for integer lists
* ---------------------------------------------------------------- */
func Min2(x int, y int) int {
if x <= y {
return x
@ -32,6 +48,49 @@ func Max2(x int, y int) int {
return y
}
func MinList(x []int) int {
var val int
if len(x) == 0 {
log.Fatal("Cannot compute the maximum of an empty array.")
return 0
}
val = x[0]
for i, val_ := range x {
if i > 0 {
val = Min2(val, val_)
}
}
return val
}
func MaxList(x []int) int {
var val int
if len(x) == 0 {
log.Fatal("Cannot compute the maximum of an empty array.")
return 0
}
val = x[0]
for i, val_ := range x {
if i > 0 {
val = Max2(val, val_)
}
}
return val
}
/* ---------------------------------------------------------------- *
* METHODS: for string lists
* ---------------------------------------------------------------- */
func StrListContains(list []string, x string) bool {
for _, obj := range list {
if obj == x {
return true
}
}
return false
}
func SortStrings(list *[]string) {
sort.Slice(*list, func(i int, j int) bool {
u := strings.ToLower((*list)[i])
@ -68,6 +127,7 @@ func UnionStrings2(list1 []string, list2 []string) []string {
return list
}
// assumes that listTo contains no duplicates
func UnionStringsTo(listTo *[]string, listFrom []string) {
var mark = make(map[string]bool)
for _, item := range listFrom {
@ -82,3 +142,11 @@ func UnionStringsTo(listTo *[]string, listFrom []string) {
}
}
}
func UnionStringsList(lists [][]string) []string {
var list = []string{}
for _, list_ := range lists {
UnionStringsTo(&list, list_)
}
return list
}

View File

@ -12,6 +12,28 @@ import (
"github.com/stretchr/testify/assert"
)
/* ---------------------------------------------------------------- *
* TESTCASE Min2, Max2, MinList, MaxList
* ---------------------------------------------------------------- */
func TestMin(test *testing.T) {
var assert = assert.New(test)
assert.Equal(3, utils.Min2(3, 8))
assert.Equal(8, utils.Min2(100, 8))
assert.Equal(50, utils.MinList([]int{50}))
assert.Equal(1, utils.MinList([]int{50, 1}))
assert.Equal(2, utils.MinList([]int{50, 34, 10, 2, 8, 89}))
}
func TestMax(test *testing.T) {
var assert = assert.New(test)
assert.Equal(8, utils.Max2(3, 8))
assert.Equal(100, utils.Max2(100, 8))
assert.Equal(50, utils.MaxList([]int{50}))
assert.Equal(50, utils.MaxList([]int{50, 1}))
assert.Equal(89, utils.MaxList([]int{50, 34, 10, 2, 8, 89}))
}
/* ---------------------------------------------------------------- *
* TESTCASE SortStrings
* ---------------------------------------------------------------- */
@ -20,7 +42,7 @@ func TestSortStrings(test *testing.T) {
var assert = assert.New(test)
var list = []string{"katze", "Hund", "baby", "Pluto", "Saturn", "Mond"}
utils.SortStrings(&list)
assert.Equal(list, []string{"baby", "Hund", "katze", "Mond", "Pluto", "Saturn"})
assert.Equal([]string{"baby", "Hund", "katze", "Mond", "Pluto", "Saturn"}, list)
}
/* ---------------------------------------------------------------- *
@ -31,11 +53,11 @@ func TestFilterStrings(test *testing.T) {
var assert = assert.New(test)
var list = []string{"abram", "aaron", "aardvark", "aarhus", "alaska", "eel", "aal"}
var list2 = utils.FilterStrings(&list, func(x string) bool { return strings.HasPrefix(x, "aa") })
assert.Equal(list2, []string{"aaron", "aardvark", "aarhus", "aal"})
assert.Equal([]string{"aaron", "aardvark", "aarhus", "aal"}, list2)
}
/* ---------------------------------------------------------------- *
* TESTCASE UnionStrings2, UnionStringsTo
* TESTCASE UnionStrings2, UnionStringsTo, UnionStringsList
* ---------------------------------------------------------------- */
func TestUnionStrings2(test *testing.T) {
@ -44,14 +66,24 @@ func TestUnionStrings2(test *testing.T) {
var list2 = []string{"yellow", "orange", "lila", "red"}
var list = utils.UnionStrings2(list1, list2)
utils.SortStrings(&list)
assert.Equal(list, []string{"black", "blue", "green", "grey", "lila", "orange", "red", "yellow"})
assert.Equal([]string{"black", "blue", "green", "grey", "lila", "orange", "red", "yellow"}, list)
}
func UnionStringsTo(test *testing.T) {
func TestUnionStringsTo(test *testing.T) {
var assert = assert.New(test)
var list1 = []string{"red", "blue", "blue", "green"}
var list2 = []string{"yellow", "red", "black"}
var list1 = []string{"red", "blue", "green"}
var list2 = []string{"yellow", "red", "blue", "red", "black"}
utils.UnionStringsTo(&list1, list2)
utils.SortStrings(&list1)
assert.Equal(list1, []string{"black", "blue", "green", "red", "yellow"})
assert.Equal([]string{"black", "blue", "green", "red", "yellow"}, list1)
}
func TestUnionStringsList(test *testing.T) {
var assert = assert.New(test)
var list []string
var lists [][]string
lists = [][]string{{"red", "blue", "blue", "green"}, {"yellow", "red", "black"}}
list = utils.UnionStringsList(lists)
utils.SortStrings(&list)
assert.Equal([]string{"black", "blue", "green", "red", "yellow"}, list)
}

View File

@ -12,25 +12,19 @@ github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -38,8 +32,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -1,12 +1,12 @@
package main
import (
"encoding/json"
"fmt"
"logik/aussagenlogik/rekursion"
"logik/aussagenlogik/schema"
"logik/aussagenlogik/syntaxbaum"
env "logik/core/environment"
"logik/core/utils"
"strings"
"github.com/lithammer/dedent"
@ -31,23 +31,10 @@ var data dataType
func main() {
// Extrahiere Daten
err := getData()
if err != nil {
return
}
getData()
// Ausdruck -> Syntaxbaum
tree, err := schema.ParseExpr(data.expr)
if err != nil {
return
}
// Methoden ausführen:
results := resultsType{
eval: rekursion.RekursivEval(tree, data.interpretation),
atoms: rekursion.RekursivAtoms(tree),
depth: rekursion.RekursivDepth(tree),
length: rekursion.RekursivLength(tree),
nParentheses: rekursion.RekursivParentheses(tree),
}
tree := schema.ParseExpr(data.expr)
results := getResults(tree)
// Resultate anzeigen:
displayResults(tree, results)
}
@ -56,12 +43,32 @@ func main() {
// SONSTIGE METHODEN
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
func getData() error {
func getData() {
env.ENV_FILE_NAME = DATA_ENV
data.expr = env.ReadEnvKey("expr")
s := env.ReadEnvKey("interpretation")
err := json.Unmarshal([]byte(s), &data.interpretation)
return err
utils.JsonToArrayOfStrings(s, &data.interpretation)
}
func getResults(tree syntaxbaum.SyntaxBaum) resultsType {
ch1 := make(chan int)
ch2 := make(chan []string)
ch3 := make(chan int)
ch4 := make(chan int)
ch5 := make(chan int)
go rekursion.RekursivEval(ch1, tree, data.interpretation)
go rekursion.RekursivAtoms(ch2, tree)
go rekursion.RekursivDepth(ch3, tree)
go rekursion.RekursivLength(ch4, tree)
go rekursion.RekursivParentheses(ch5, tree)
// Methoden ausführen:
return resultsType{
eval: <-ch1,
atoms: <-ch2,
depth: <-ch3,
length: <-ch4,
nParentheses: <-ch5,
}
}
func displayResults(tree syntaxbaum.SyntaxBaum, results resultsType) {
@ -82,7 +89,7 @@ func displayResults(tree syntaxbaum.SyntaxBaum, results resultsType) {
* noch nicht implementiert!
Challenge: schreibe diese Methoden! (siehe README.md)
`),
tree.Expr,
tree.GetExpr(),
tree.Pretty(" "),
strings.Join(data.interpretation, ", "),
results.eval,