%load_ext hyPLCParser
#%reload_ext hyPLCParser

"""
Explanation: <img src="plcparser_icon.png" />
<center>$A \land B \land C$</center>
PLCParser implemented in Hy ~language
See also:

Propositional Logic Clause Parser main project hub
Jupyter notebook with Calypso Hy kernel

Magics
Load extension for using magics on the document:
End of explanation
"""


%plc (1 and? 1)

%plc (True ⊕ False ⊕ True ⊕ False ⊕ True)

%plc ( ( ∧ 1 1 1 ) ∨ ( ∧ 1 1 0 ) )

"""
Explanation: Line magics
Prefix and infix support
End of explanation
"""


%%plc
#$(1 and? (or? 0 1))

"""
Explanation: Cell magics
Prefix and infix support
End of explanation
"""


%%plc
; register + sign for infix notation
#>+
; evaluate code
#$(1 + (2 + (3)))

"""
Explanation: Registering additional operators
End of explanation
"""


%%plc

; use operator macro to add mean operator with custom symbol
(defoperator mean x̄ [&rest args]
  (/ (sum args) (len args)))

; try prefix notation with nested structure
(print (x̄ 1 2 3 4))
(print (x̄ 1 2 (x̄ 3 4)))

; note that infix notation in cell magics needs to be prefixed with 
; #$ reader macro marker while in line magics it is not required
(print #$(1 x̄ 2 x̄ 3 x̄ 4))

"""
Explanation: Adding more complex custom operators
End of explanation
"""


%%plc

(defoperators * +)
(print "First"
  (defmixfix 1 + 2 * 3))

(defprecedence * +)
(print "Second"
  (defmixfix 1 + 2 * 3))

"""
Explanation: Order of precedence
By default order of precedence is from left to right. Here we will use defoperators to define additional operators beyond logical ones. Then for variety we use defmixfix macro to evaluate clause. First evaluation will give 9 as an answer because evaluation is started from 1 + 2 and then that is multiplied
End of explanation
"""


# the first line is hy code supporting infix and prefix logical clauses
%plc ( 1 and? 1 or? (0) )

# the second line is python code. this is possible because above code is line magics
[a for a in (1, 2, 3)]

"""
Explanation: Mixing Hy and Python on same cell
End of explanation
"""


%%plc

; just define a function ...
(defn f [x] (print x))

; ... and call it
(f 3.1416)

; cant use python code in plc cell magics!

%%plc

; set up variables
(setv A True B True C True)
(setv clause "( A ∧ B ∧ C )")

; use variables on clause
(print clause "=" #$( A ∧ B ∧ C ))

"""
Explanation: Normal Hy language support
End of explanation
"""


