Compare commits
9 Commits
39be87d52f
...
d877f3905c
Author | SHA1 | Date | |
---|---|---|---|
d877f3905c | |||
38c4614e3e | |||
888728d039 | |||
0856bfc0b0 | |||
b315e666b8 | |||
3b1c190543 | |||
6d774a6a4c | |||
79bfcf57bb | |||
9b225b0551 |
23
codego/aussagenlogik/formulae/formulae_advanced.go
Normal file
23
codego/aussagenlogik/formulae/formulae_advanced.go
Normal file
@ -0,0 +1,23 @@
|
||||
package formulae
|
||||
|
||||
/* ---------------------------------------------------------------- *
|
||||
* METHOD Get Atoms
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func schemeGetAtoms(fml Formula, prevValues [](*[]Formula)) *[]Formula {
|
||||
if fml.IsAtom() {
|
||||
return &[]Formula{fml.Copy()}
|
||||
} else {
|
||||
var results = []Formula{}
|
||||
for _, prevValue := range prevValues {
|
||||
results = append(results, *prevValue...)
|
||||
}
|
||||
return &results
|
||||
}
|
||||
}
|
||||
|
||||
var fnGetAtoms = CreateFromSchemeFmlsValued(schemeGetAtoms)
|
||||
|
||||
func (fml Formula) GetAtoms() []Formula {
|
||||
return *fnGetAtoms(fml)
|
||||
}
|
@ -11,6 +11,7 @@ import (
|
||||
|
||||
type Formula struct {
|
||||
kind string
|
||||
name string
|
||||
expr string
|
||||
valence int
|
||||
subformulae [](*Formula)
|
||||
@ -28,18 +29,38 @@ 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) 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 children = make([]Formula, n)
|
||||
var subfmls = make([]Formula, n)
|
||||
for i, subfml := range fml.subformulae {
|
||||
children[i] = *subfml
|
||||
subfmls[i] = *subfml
|
||||
}
|
||||
return children
|
||||
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 {
|
||||
@ -84,17 +105,27 @@ func (fml Formula) pretty(preindent string, tab string, prepend string, depth in
|
||||
}
|
||||
}
|
||||
|
||||
// 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 children = make([](*Formula), len(fml.subformulae))
|
||||
for i, child := range fml.subformulae {
|
||||
childCopy := child.Deepcopy()
|
||||
children[i] = &childCopy
|
||||
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: children,
|
||||
subformulae: subfmls,
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,3 +148,4 @@ func (fml Formula) IsConjunction() bool { return fml.kind == "and" || fm
|
||||
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" }
|
||||
|
@ -22,23 +22,25 @@ var Contradiction = Formula{
|
||||
* METHODS: Constructions
|
||||
* ---------------------------------------------------------------- */
|
||||
|
||||
func Atom(expr string) Formula {
|
||||
func Atom(name string) Formula {
|
||||
return Formula{
|
||||
kind: "atom",
|
||||
expr: expr,
|
||||
name: name,
|
||||
expr: name,
|
||||
valence: 0,
|
||||
subformulae: [](*Formula){},
|
||||
}
|
||||
}
|
||||
|
||||
func NegatedAtom(expr string) Formula {
|
||||
return Negation(Atom(expr))
|
||||
func NegatedAtom(name string) Formula {
|
||||
return Negation(Atom(name))
|
||||
}
|
||||
|
||||
func Generic(expr string) Formula {
|
||||
func Generic(name string) Formula {
|
||||
return Formula{
|
||||
kind: "generic",
|
||||
expr: expr,
|
||||
name: name,
|
||||
expr: "{" + name + "}",
|
||||
valence: 0,
|
||||
subformulae: [](*Formula){},
|
||||
}
|
||||
@ -115,3 +117,12 @@ func Implies(fml1 Formula, fml2 Formula) Formula {
|
||||
subformulae: [](*Formula){&fml1, &fml2},
|
||||
}
|
||||
}
|
||||
|
||||
func DoubleImplication(fml1 Formula, fml2 Formula) Formula {
|
||||
return Formula{
|
||||
kind: "iff",
|
||||
expr: "(" + fml1.expr + " <-> " + fml2.expr + ")",
|
||||
valence: 2,
|
||||
subformulae: [](*Formula){&fml1, &fml2},
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ func Eval(fml formulae.Formula, I []string) int {
|
||||
var schema = func(_I []string) func(formulae.Formula, []int) int {
|
||||
return func(fml formulae.Formula, prevValues []int) int {
|
||||
if fml.IsAtom() || fml.IsGeneric() {
|
||||
return utils.BoolToInt(utils.StrListContains(_I, fml.GetExpr()))
|
||||
return utils.BoolToInt(utils.StrListContains(_I, fml.GetName()))
|
||||
} else if fml.IsTautologySymbol() {
|
||||
return 1
|
||||
} else if fml.IsContradictionSymbol() {
|
||||
@ -31,6 +31,8 @@ func Eval(fml formulae.Formula, I []string) int {
|
||||
return utils.MaxList(prevValues)
|
||||
} else if fml.IsImplication() {
|
||||
return utils.BoolToInt(prevValues[0] <= prevValues[1])
|
||||
} else if fml.IsDoubleImplication() {
|
||||
return utils.BoolToInt(prevValues[0] == prevValues[1])
|
||||
} else {
|
||||
panic("Could not evaluate expression!")
|
||||
}
|
||||
|
@ -64,9 +64,20 @@ func NNF(fml formulae.Formula) formulae.Formula {
|
||||
}
|
||||
} else if fml.IsImplication() {
|
||||
return formulae.FormulaPair{
|
||||
Pos: formulae.Implies(prevPos[0], prevPos[1]),
|
||||
Pos: formulae.Disjunction2(prevNeg[0], prevPos[1]),
|
||||
Neg: formulae.Conjunction2(prevPos[0], prevNeg[1]),
|
||||
}
|
||||
} else if fml.IsDoubleImplication() {
|
||||
return formulae.FormulaPair{
|
||||
Pos: formulae.Conjunction2(
|
||||
formulae.Disjunction2(prevNeg[0], prevPos[1]),
|
||||
formulae.Disjunction2(prevNeg[1], prevPos[0]),
|
||||
),
|
||||
Neg: formulae.Disjunction2(
|
||||
formulae.Conjunction2(prevPos[0], prevNeg[1]),
|
||||
formulae.Conjunction2(prevPos[1], prevNeg[0]),
|
||||
),
|
||||
}
|
||||
} else {
|
||||
panic("Could not evaluate expression!")
|
||||
}
|
||||
|
@ -23,25 +23,124 @@ func TestEvalLiteral(test *testing.T) {
|
||||
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) {
|
||||
func TestEvalNegation(test *testing.T) {
|
||||
var assert = assert.New(test)
|
||||
var val int
|
||||
var fml formulae.Formula
|
||||
var I []string
|
||||
|
||||
fml = schema.ParseExpr("A4 || ! A4")
|
||||
I = []string{}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(1, val)
|
||||
|
||||
fml = schema.ParseExpr("A4 && ! A4")
|
||||
I = []string{}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(0, val)
|
||||
}
|
||||
|
||||
func TestEvalConjunction(test *testing.T) {
|
||||
var assert = assert.New(test)
|
||||
var val int
|
||||
var fml formulae.Formula
|
||||
var I []string
|
||||
|
||||
fml = schema.ParseExpr("A0 && A1")
|
||||
I = []string{"A0"}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(0, val)
|
||||
|
||||
fml = schema.ParseExpr("A0 && A1")
|
||||
I = []string{"A0", "A1"}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(1, val)
|
||||
}
|
||||
|
||||
func TestEvalDisjunction(test *testing.T) {
|
||||
var assert = assert.New(test)
|
||||
var val int
|
||||
var fml formulae.Formula
|
||||
var I []string
|
||||
|
||||
fml = schema.ParseExpr("A0 || A1")
|
||||
I = []string{"A0"}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(1, val)
|
||||
|
||||
fml = schema.ParseExpr("A0 || A1")
|
||||
I = []string{"A7"}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(0, val)
|
||||
}
|
||||
|
||||
func TestEvalImplication(test *testing.T) {
|
||||
var assert = assert.New(test)
|
||||
var val int
|
||||
var fml formulae.Formula
|
||||
var I []string
|
||||
|
||||
fml = schema.ParseExpr("A0 -> A1")
|
||||
I = []string{"A0"}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(0, val)
|
||||
|
||||
fml = schema.ParseExpr("A0 -> A1")
|
||||
I = []string{"A0", "A1"}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(1, val)
|
||||
|
||||
fml = schema.ParseExpr("A0 -> A1")
|
||||
I = []string{"A7"}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(1, val)
|
||||
}
|
||||
|
||||
func TestEvalIff(test *testing.T) {
|
||||
var assert = assert.New(test)
|
||||
var val int
|
||||
var fml formulae.Formula
|
||||
var I []string
|
||||
|
||||
fml = schema.ParseExpr("A0 <-> A1")
|
||||
I = []string{"A0"}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(0, val)
|
||||
|
||||
fml = schema.ParseExpr("A0 <-> A1")
|
||||
I = []string{"A0", "A1"}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(1, val)
|
||||
|
||||
fml = schema.ParseExpr("A0 <-> A1")
|
||||
I = []string{"A7"}
|
||||
val = recursion.Eval(fml, I)
|
||||
assert.Equal(1, val)
|
||||
}
|
||||
|
||||
func TestEvalComplex(test *testing.T) {
|
||||
var assert = assert.New(test)
|
||||
var val int
|
||||
var fml formulae.Formula
|
||||
@ -50,26 +149,24 @@ func TestEvalComplex1(test *testing.T) {
|
||||
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)
|
||||
@ -90,9 +187,8 @@ func TestAtomsNoduplicates(test *testing.T) {
|
||||
assert.Equal(1, n, "Atome dürfen nicht mehrfach vorkommen!")
|
||||
}
|
||||
|
||||
func TestAtomsNononatoms(test *testing.T) {
|
||||
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
|
||||
@ -298,12 +394,14 @@ func TestNNFatoms(test *testing.T) {
|
||||
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())
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package schema
|
||||
import (
|
||||
"logik/aussagenlogik/formulae"
|
||||
parser "logik/grammars/aussagenlogik"
|
||||
"regexp"
|
||||
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
)
|
||||
@ -65,22 +66,13 @@ func (ant antlrTree) getLabel() string {
|
||||
}
|
||||
|
||||
func (ant antlrTree) getTextContent() string {
|
||||
var expr string = ant.getLabel()
|
||||
for _, subant := range ant.getChildren() {
|
||||
expr += subant.getTextContent()
|
||||
}
|
||||
return expr
|
||||
}
|
||||
|
||||
func (ant antlrTree) getTextContentLeaves() string {
|
||||
var expr string = ""
|
||||
var subants = ant.getChildren()
|
||||
if len(subants) == 0 {
|
||||
expr = ant.getLabel()
|
||||
} else {
|
||||
for _, subant := range subants {
|
||||
expr += subant.getTextContent()
|
||||
}
|
||||
return ant.getLabel()
|
||||
}
|
||||
for _, subant := range subants {
|
||||
expr += subant.getTextContent()
|
||||
}
|
||||
return expr
|
||||
}
|
||||
@ -116,9 +108,12 @@ func (ant antlrTree) toFormula() formulae.Formula {
|
||||
case "contradiction":
|
||||
return formulae.Contradiction
|
||||
case "atom":
|
||||
return formulae.Atom(ant.getTextContentLeaves())
|
||||
name := ant.getTextContent()
|
||||
return formulae.Atom(name)
|
||||
case "generic":
|
||||
return formulae.Generic(ant.getTextContentLeaves())
|
||||
re := regexp.MustCompile(`^{|}$`)
|
||||
name := string(re.ReplaceAll([]byte(ant.getTextContent()), []byte("")))
|
||||
return formulae.Generic(name)
|
||||
case "not":
|
||||
// NOTE: expr = ! expr
|
||||
if nChildren == 2 {
|
||||
@ -139,6 +134,11 @@ func (ant antlrTree) toFormula() formulae.Formula {
|
||||
if nChildren == 3 {
|
||||
return formulae.Implies(subants[0].toFormula(), subants[2].toFormula())
|
||||
}
|
||||
case "iff":
|
||||
// NOTE: expr = expr <=> expr
|
||||
if nChildren == 3 {
|
||||
return formulae.DoubleImplication(subants[0].toFormula(), subants[2].toFormula())
|
||||
}
|
||||
case "and", "or":
|
||||
// NOTE: expr = expr op expr op ... op expr
|
||||
var n int = int((len(subants) + 1) / 2)
|
||||
|
@ -7,27 +7,29 @@ LBRACE: '(';
|
||||
RBRACE: ')';
|
||||
LCURLYBRACE: '{';
|
||||
RCURLYBRACE: '}';
|
||||
TEXT: [a-zA-Z0-9\\_];
|
||||
|
||||
// Symbole (erlaube mehrere Varianten)
|
||||
SYMB_NOT: ('!'|'~'|'not');
|
||||
SYMB_AND: ('&'+|'^'|'and');
|
||||
SYMB_OR: ('|'+|'v'|'or');
|
||||
SYMB_IMPL: ('->'|'=>');
|
||||
SYMB_IFF: ([<][-]+[>]|[<][=]+[>]|'iff');
|
||||
SYMB_IMPL: (~[<][-]+[>]|~[<][=]+[>]);
|
||||
|
||||
// Rules
|
||||
start: open <EOF> | closed <EOF>;
|
||||
|
||||
closed: atomic | not | LBRACE open RBRACE;
|
||||
open: and2 | and | or2 | or | implies;
|
||||
open: and2 | and | or2 | or | implies | iff;
|
||||
|
||||
// Schemata für atomische Ausdrücke
|
||||
atomic: taut | contradiction | atom; //| generic;
|
||||
atomic: taut | contradiction | atom | generic;
|
||||
taut: ('1'|'true');
|
||||
contradiction: ('0'|'false');
|
||||
atom: 'A0' | 'A1' | 'A' NUMBER; // muss A0, A1 wegen falsum/verum extra auflisten
|
||||
// // als 'generische' Formeln schreibe bspw. {F}, {G}, {F1}, usw.
|
||||
// // generic: LCURLYBRACE (.*?) RCURLYBRACE;
|
||||
// FIXME: dieses Schema führt zu Konflikten
|
||||
// als 'generische' Formeln schreibe bspw. {F}, {G}, usw.
|
||||
generic: LCURLYBRACE TEXT+ RCURLYBRACE | LCURLYBRACE TEXT* ( generic TEXT* )+ RCURLYBRACE;
|
||||
// FIXME: liest Zahlen schlecht ein
|
||||
|
||||
// Schema für Negation: ¬ F
|
||||
not: symb=SYMB_NOT closed;
|
||||
@ -39,3 +41,5 @@ or2: closed symb=SYMB_OR closed;
|
||||
or: ( closed ( symb=SYMB_OR closed )+ );
|
||||
// Schema für Implikation: F1 ⟶ F2
|
||||
implies: closed symb=SYMB_IMPL closed;
|
||||
// Schema für Implikation: F1 ⟷ F2
|
||||
iff: closed symb=SYMB_IFF closed;
|
||||
|
@ -16,7 +16,6 @@ function call_go() {
|
||||
}
|
||||
|
||||
function check_requirements() {
|
||||
[ -f "go.sum" ] && rm "go.sum";
|
||||
call_go get "$( cat scripts/requirements )";
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user