Coverage for src/SymbSyntDec/snf.py: 55%

1

2 from pylogics_modalities.parsers import parse_pltl

3 from functools import singledispatch

4

5 from pylogics_modalities.parsers import parse_pltl

6 from pylogics_modalities.syntax.base import (

7 And as PLTLAnd,

8 Or as PLTLOr,

9 Formula,

10 Implies as PLTLImplies,

11 Not as PLTLNot,

12 _UnaryOp

13)

14 from pylogics_modalities.syntax.pltl import (

15 Atomic as PLTLAtomic,

16 Before,

17 WeakBefore,

18 FalseFormula,

19 Historically,

20 Once,

21 PropositionalFalse,

22 PropositionalTrue,

23 Since,

24 Triggers

25)

26

27 Sigma = None

28

29

30 def snf_unaryop(formula: _UnaryOp):

31 return snf_operands(formula.argument)

32

33

34 def snf(formula: object, closure: set) -> Formula:

35 global Sigma

36 Sigma = closure

37 return snf_operands(formula)

38

39

40@singledispatch

41 def snf_operands(formula: object) -> Formula:

42 raise NotImplementedError(

43 f"State_variables not implemented for object of type {type(formula)}"

44 )

45

46

47@snf_operands.register

48 def snf_prop_true(formula: PropositionalTrue) -> Formula:

49 return formula

50

51

52@snf_operands.register

53 def snf_prop_false(formula: PropositionalFalse) -> Formula:

54 return formula

55

56

57@snf_operands.register

58 def snf_false(formula: FalseFormula) -> Formula:

59 return formula

60

61

62@snf_operands.register

63 def snf_atomic(formula: PLTLAtomic) -> Formula:

64 if formula in Sigma:

65 return formula

66 return None

67

68

69@snf_operands.register

70 def snf_and(formula: PLTLAnd) -> Formula:

71 sub = [snf_operands(f) for f in formula.operands]

72 return PLTLAnd(*sub)

73

74

75@snf_operands.register

76 def snf_or(formula: PLTLOr) -> Formula:

77 sub = [snf_operands(f) for f in formula.operands]

78 return PLTLOr(*sub)

79

80

81@snf_operands.register

82 def snf_not(formula: PLTLNot) -> Formula:

83 temp = snf_unaryop(formula)

84 return PLTLNot(temp)

85

86

87@snf_operands.register

88 def snf_implies(formula: PLTLImplies) -> Formula:

89 """Compute the base formula for an Implies formula. Returns A DNF formula"""

90 head = [PLTLNot(snf_operands(f))

91 for f in formula.operands[:-1]]

92 tail = formula.operands[-1]

93 return PLTLOr(*head, tail)

94

95

96@snf_operands.register

97 def snf_yesterday(formula: Before) -> Formula:

98 """Compute the base formula for a Before (Yesterday) formula."""

99 return Before(snf_unaryop(formula))

100

101

102@snf_operands.register

103 def snf_weak_yesterday(formula: WeakBefore) -> Formula:

104 """Compute the base formula for a WeakBefore (Weak Yesterday) formula."""

105 return WeakBefore(snf_unaryop(formula))

106

107

108@snf_operands.register

109 def snf_since(formula: Since) -> Formula:

110 """Compute the base formula for a Since formulas."""

111 sub1 = snf_operands(formula.operands[0])

112 sub2 = snf_operands(formula.operands[1])

113 sub3 = Before(formula)

114 return (PLTLOr(sub2, (PLTLAnd(sub1, sub3))))

115

116

117@snf_operands.register

118 def snf_since(formula: Triggers) -> Formula:

119 sub1 = snf_operands(formula.operands[0])

120 sub2 = snf_operands(formula.operands[1])

121 sub3 = WeakBefore(formula)

122 return (PLTLAnd(sub2, (PLTLOr(sub1, sub3))))

123

124

125'''

126# Examples:

127 formula_str = "!a S H(a)" # a T (Y b)

128 print(formula_str)

129 formula_pltl = parse_pltl(formula_str)

130 print(formula_pltl)

131# should be modifies to ( !a S (false T a))

132# (since (not a) (triggers false a))

133 formula_modified = modify(formula_pltl)

134 print(formula_modified)

135# should return: {a, !a, b, !b, a T (Y b) , Y b, Z (a T (Y b) ) }

136 snf_set_return = snf(formula_mogdified)

137

138'''