Create a gist now

Instantly share code, notes, and snippets.

Jess wiki ant simulator using modules
;; Module Ant Simulator
;; Modified slightly by Daniel Alberto Cañas
;; Based on Salient Ant Simulator
;; by Jason Morris
;; found at http://www.jessrules.com/jesswiki/view?SalientAntSimulator
(clear)
;; An ant's priorities in order of importance
;; Threat (Enemy attacking)
;; Work (Gather food)
;; Chore (Take out garbage)
;; Useful variables
(defglobal ?*max* = 65536)
(defglobal ?*enemy-total* = 0)
(defglobal ?*survival-probability* = 0.5)
(defglobal ?*survival-limit* = 0.75)
(defquery all-ants
"Finds all ants."
(ant ?ant))
(defquery all-enemy-ants
"Finds all the enemy ants."
(enemy-ant ?enemy-ant))
(defquery all-predators
"Find number of predators."
(predator ?predator))
(defquery all-food-sources
"Finds all the food sorces available."
(food-source ?food-source))
(defquery all-garbage-sources
"Finds all the garbage sources available."
(garbage-source ?garbage-source))
;; Next, let's give our ant some behaviors
(deffunction gather-food (?food)
(retract ?food)
(printout t "Food item gathered OK" crlf))
(deffunction take-out-garbage (?item)
(retract ?item)
(printout t "Garbage emptied OK" crlf))
;; If he gets killed, then see if he was a hero to the colony
(deffunction check-hero-ant()
(if (>= ?*enemy-total* 5) then
(printout t "This ant was a hero!" crlf)))
(deffunction attack-ant (?ant)
(printout t "Attacking enemy ant..." crlf)
(bind ?survival-ratio (/ (random) ?*max*))
(if (>= ?*survival-probability* ?survival-ratio) then
(printout t "Enemy ant killed :-D " ?ant crlf)
;; Give credit for surviving
(bind ?*enemy-total* (+ ?*enemy-total* 1))
;; Account for increased experience up to a point
(if (< ?*survival-probability* ?*survival-limit*) then
(bind ?*survival-probability* (+ ?*survival-probability* 0.05)))
(retract ?ant) else
(printout t "Ant killed by enemy :-( " ?ant crlf)
(check-hero-ant)
(halt)))
;; Have nature disturb the environment in a few ways
(deffunction change-ant-environment()
(if (>= (/ (random) ?*max*) 0.25) then
(assert (food-source (gensym*))))
(if (>= (/ (random) ?*max*) 0.9) then
(assert (enemy-ant (gensym*)))
(printout t "Enemy Ant has appeared." crlf)))
;; We'll give a 50% chance of a predator appearing
(deffunction get-predator()
(if (>= (/ (random) ?*max*) 0.5) then
(assert (predator (gensym*))))
(printout t "A predator has appeared!" crlf)
;; Unfortunately, predators stir up food items, so
(assert (food-source (gensym*))))
;; We'll give a 50% chance of existing predator leaving
(deffunction remove-predator(?predator)
(if (>= (/ (random) ?*max*) 0.5) then
(retract ?predator)
(printout t "Predator has gone away." crlf)))
;; And 75% chance of being eaten
(deffunction is-ant-eaten()
(if (>= (/ (random) ?*max*) 0.25) then
(printout t "Arrg! Ant got eaten!" crlf)
(halt) else
(printout t "Ant avoided predator OK" crlf)))
;; A header
(deffunction print-banner()
(printout t "Module Ant Simulator" crlf)
(printout t "---------------------" crlf))
(deffunction debug()
(bind ?ants (count-query-results all-ants))
(bind ?enemy-ants (count-query-results all-enemy-ants))
(bind ?predators (count-query-results all-predators))
(bind ?food (count-query-results all-food-sources))
(bind ?garbage (count-query-results all-garbage-sources))
(printout t (get-focus-stack) " ")
(facts *)
(printout t ?ants " ants. " ?enemy-ants " enemy ants. " ?predators " predators. ")
(printout t ?food " food left. " ?garbage " garbage left." crlf))
;; Now we define what causes those behaviors to happen.
;; We can hypothesize that everything the ant does
;; influences its environment in some way.
;; NATURE
(defrule food-attracts-ants
(exists (food-source ?))
=>
(assert(ant (gensym*))))
(defrule ant-attracts-other-ants
(exists (ant ?))
=>
; twice as many
(assert(enemy-ant (gensym*)))
(assert(ant (gensym*)))
(assert(ant (gensym*))))
;;(defmodule NO)
(defrule add-a-predator
(not (predator ?))
=>
(get-predator))
(defrule remove-a-predator
?p<- (predator ?)
=>
(remove-predator ?p))
(defrule MAIN::ant-got-eaten
(predator ?)
=>
(is-ant-eaten))
(defrule MAIN::nothing-to-do
(not (food-source ?)) ; Nothing to eat
(not (garbage-source ?)) ; Nothing to clean
(not (enemy-ant ?)) ; Nothing to fight
=>
(printout t "Ant survived simulation!" crlf)
;(agenda)
(halt))
(defmodule THREAT)
(defrule attack-enemy-ant
(declare (auto-focus TRUE))
?ant <-(enemy-ant ?)
=>
(printout t "Enemy appeared... Will attack." crlf)
(attack-ant ?ant)
(change-ant-environment))
(defmodule WORK)
(defrule gather-food
?food <- (food-source ?)
=>
(gather-food ?food)
(change-ant-environment))
;; CHORES
(defmodule CHORE)
(defrule take-out-garbage
?item <-(garbage-source ?)
=>
(take-out-garbage ?item)
(change-ant-environment))
;; Return to gathering food.
(defrule there-is-food
(exists (food-source ?))
=>
(printout t "Still food silly." crlf)
(focus WORK))
;; Finally, let's give the ant some things to do
(deffacts ant-environment
(food-source 1)
(garbage-source 1)
(food-source 2)
(garbage-source 2)
(food-source 3)
(food-source 4)
(food-source 5)
)
;; Run our little ant world
;(watch focus)
(reset)
(print-banner)
(focus WORK CHORE)
(run-until-halt)
@dacamo76
Owner

This is my intent to learn more about Jess modules. I took Jason Morris' Salient Ant Simulator example and changed it to use modules. The simulator shows how to use salience to partition rules into groups, since that is what Jess modules do, it's a great example to tweak and understand modules.

@dacamo76
Owner

I changed the file ending to .lisp from .clp just for syntax highlighting purposes. Gist does not understand .clp and Jess/Clips is close enough to lisp to get some highlighting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment