xcsp-lang.lisp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. ;;;; xcsp-lang.lisp
  2. ;;;;
  3. ;;;; Copyright (c) 2020 Samuel W. Flint <swflint@flintfam.org>
  4. (in-package #:lcsp-xcsp-lang)
  5. ;;; "lcsp-xcsp-lang" goes here.
  6. (defrule integral (and (? #\-) (+ (character-ranges (#\0 #\9))))
  7. (:text t)
  8. (:function parse-integer))
  9. (defrule bool (or "true" "false")
  10. (:text t)
  11. (:lambda (expr)
  12. (string= expr "true")))
  13. (defrule identifier (+ (character-ranges (#\A #\Z) (#\a #\z) (#\0 #\9)))
  14. (:text t)
  15. (:lambda (text)
  16. (symbolicate (string-upcase text))))
  17. (defrule int-expr (or integral absv neg add sub mul div modr powr minr maxr if-then identifier))
  18. (defrule neg (and "neg(" int-expr ")")
  19. (:destructure (_ expr __)
  20. (declare (ignore _ __))
  21. `(- ,expr)))
  22. (defrule absv (and "abs(" int-expr ")")
  23. (:destructure (_ expr __)
  24. (declare (ignore _ __))
  25. `(abs ,expr)))
  26. (defrule add (and "add(" int-expr "," int-expr ")")
  27. (:destructure (_ expr-a __ expr-b ___)
  28. (declare (ignore _ __ ___))
  29. `(+ ,expr-a ,expr-b)))
  30. (defrule sub
  31. (and "sub(" int-expr "," int-expr ")")
  32. (:destructure (_ expr-a __ expr-b ___)
  33. (declare (ignore _ __ ___))
  34. `(- ,expr-a ,expr-b)))
  35. (defrule mul
  36. (and "mul(" int-expr "," int-expr ")")
  37. (:destructure (_ expr-a __ expr-b ___)
  38. (declare (ignore _ __ ___))
  39. `(* ,expr-a ,expr-b)))
  40. (defrule div
  41. (and "div(" int-expr "," int-expr ")")
  42. (:destructure (_ expr-a __ expr-b ___)
  43. (declare (ignore _ __ ___))
  44. `(/ ,expr-a ,expr-b)))
  45. (defrule modr
  46. (and "mod(" int-expr "," int-expr ")")
  47. (:destructure (_ expr-a __ expr-b ___)
  48. (declare (ignore _ __ ___))
  49. `(mod ,expr-a ,expr-b)))
  50. (defrule powr
  51. (and "pow(" int-expr "," int-expr ")")
  52. (:destructure (_ expr-a __ expr-b ___)
  53. (declare (ignore _ __ ___))
  54. `(expt ,expr-a ,expr-b)))
  55. (defrule minr
  56. (and "min(" int-expr "," int-expr ")")
  57. (:destructure (_ expr-a __ expr-b ___)
  58. (declare (ignore _ __ ___))
  59. `(min ,expr-a ,expr-b)))
  60. (defrule maxr
  61. (and "max(" int-expr "," int-expr ")")
  62. (:destructure (_ expr-a __ expr-b ___)
  63. (declare (ignore _ __ ___))
  64. `(max ,expr-a ,expr-b)))
  65. (defrule if-then (and "if(" bool-expr "," int-expr "," int-expr ")")
  66. (:destructure (_ condition __ true-case ___ false-case ____)
  67. (declare (ignore _ __ ___ ____))
  68. `(if ,condition ,true-case ,false-case)))
  69. (defrule bool-expr (or not-expr and-expr or-expr iff-expr eq-expr neq-expr ge-expr gt-expr le-expr lt-expr bool))
  70. (defrule not-expr (and "not(" bool-expr ")")
  71. (:destructure (_ bool-expr __)
  72. (declare (ignore _ __))
  73. `(not ,bool-expr)))
  74. (defrule and-expr
  75. (and "and(" bool-expr "," bool-expr ")")
  76. (:destructure (_ expr-a __ expr-b ___) (declare (ignore _ __ ___))
  77. `(and ,expr-a ,expr-b)))
  78. (defrule or-expr
  79. (and "or(" bool-expr "," bool-expr ")")
  80. (:destructure (_ expr-a __ expr-b ___) (declare (ignore _ __ ___))
  81. `(or ,expr-a ,expr-b)))
  82. (defun iff (a b)
  83. (and (or (not a) b)
  84. (or (not b) a)))
  85. (defrule iff-expr
  86. (and "iff(" bool-expr "," bool-expr ")")
  87. (:destructure (_ expr-a __ expr-b ___)
  88. (declare (ignore _ __ ___))
  89. `(iff ,expr-a ,expr-b)))
  90. (defrule eq-expr
  91. (and "eq(" int-expr "," int-expr ")")
  92. (:destructure (_ expr-a __ expr-b ___)
  93. (declare (ignore _ __ ___))
  94. `(= ,expr-a ,expr-b)))
  95. (defrule neq-expr
  96. (and "ne(" int-expr "," int-expr ")")
  97. (:destructure (_ expr-a __ expr-b ___)
  98. (declare (ignore _ __ ___))
  99. `(not (= ,expr-a ,expr-b))))
  100. (defrule ge-expr
  101. (and "ge(" int-expr "," int-expr ")")
  102. (:destructure (_ expr-a __ expr-b ___)
  103. (declare (ignore _ __ ___))
  104. `(>= ,expr-a ,expr-b)))
  105. (defrule gt-expr
  106. (and "gt(" int-expr "," int-expr ")")
  107. (:destructure (_ expr-a __ expr-b ___)
  108. (declare (ignore _ __ ___))
  109. `(> ,expr-a ,expr-b)))
  110. (defrule le-expr
  111. (and "le(" int-expr "," int-expr ")")
  112. (:destructure (_ expr-a __ expr-b ___)
  113. (declare (ignore _ __ ___))
  114. `(<= ,expr-a ,expr-b)))
  115. (defrule lt-expr
  116. (and "lt(" int-expr "," int-expr ")")
  117. (:destructure (_ expr-a __ expr-b ___)
  118. (declare (ignore _ __ ___))
  119. `(< ,expr-a ,expr-b)))
  120. (defun parse-xcsp-predicate (expression-string arguments-list &key (compile-p t))
  121. (let* ((expression (parse 'bool-expr expression-string))
  122. (xcsp-function-expression `(lambda (,@arguments-list) ,expression)))
  123. (if compile-p
  124. (compile nil xcsp-function-expression)
  125. (eval xcsp-function-expression))))
  126. ;;; End lcsp-xcsp-lang