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

64 statements  

« prev     ^ index     » next       coverage.py v7.5.4, created at 2024-08-11 18:00 +0200

1 

2from pylogics_modalities.parsers import parse_pltl 

3from functools import singledispatch 

4 

5from pylogics_modalities.parsers import parse_pltl 

6from 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) 

14from 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 

27Sigma = None 

28 

29 

30def snf_unaryop(formula: _UnaryOp): 

31 return snf_operands(formula.argument) 

32 

33 

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

35 global Sigma 

36 Sigma = closure 

37 return snf_operands(formula) 

38 

39 

40@singledispatch 

41def 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 

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

49 return formula 

50 

51 

52@snf_operands.register 

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

54 return formula 

55 

56 

57@snf_operands.register 

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

59 return formula 

60 

61 

62@snf_operands.register 

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

64 if formula in Sigma: 

65 return formula 

66 return None 

67 

68 

69@snf_operands.register 

70def 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 

76def 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 

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

83 temp = snf_unaryop(formula) 

84 return PLTLNot(temp) 

85 

86 

87@snf_operands.register 

88def 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 

97def 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 

103def 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 

109def 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 

118def 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: 

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

128print(formula_str) 

129formula_pltl = parse_pltl(formula_str) 

130print(formula_pltl) 

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

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

133formula_modified = modify(formula_pltl) 

134print(formula_modified) 

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

136snf_set_return = snf(formula_mogdified) 

137 

138'''