Demo entry 6361778

Test

   

Submitted by anonymous on May 05, 2017 at 12:41
Language: Scala. Code size: 17.5 kB.

/* -------------------------------------------------------------------------- 

   Complete code for the command-line interpreter


   AUTHOR : K. Désiron
   DATE   : April 2017

----------------------------------------------------------------------------*/

/*
 * Implémentation d'une liste chaînée pour stoquer les paires d'éléments d'un espace de tuple des foncteurs.
 */
class Tuple
case class simple_tuple(name: String, psiTerm: PsiTerm) extends Tuple
case class complex_tuple(name: String, psiTerm: PsiTerm, next: Tuple) extends Tuple

/*
 * Implémentation des psi-term.
 */
class PsiTerm
case class foncteur(name: String, tuple: Tuple) extends PsiTerm
case class psi_string(s: String) extends PsiTerm
case class psi_int(i: Int) extends PsiTerm
case class psi_com_var(s: String) extends PsiTerm

class Expr
case class bacht_ast_empty_agent() extends Expr
case class bacht_ast_primitive(primitive: String, f: foncteur) extends Expr
case class bacht_ast_agent(op: String, agenti: Expr, agentii: Expr) extends Expr

object Tools{
   def match_tuple(x: Tuple, y: Tuple): Boolean = (x, y) match {
    case (complex_tuple(n1, p1, next1), complex_tuple(n2, p2, next2)) => ((n1.compareTo(n2) == 0 && Tools.match_psi_term(p1, p2)) || Tools.match_tuple(next1, simple_tuple(n2, p2))) && Tools.match_tuple(next1, next2)
    case (complex_tuple(n1, p1, next1), simple_tuple(n2, p2)) => (n1.compareTo(n2) == 0 && Tools.match_psi_term(p1, p2)) || Tools.match_tuple(next1, simple_tuple(n2, p2))
    case (simple_tuple(n1, p1), simple_tuple(n2, p2)) => n1.compareTo(n2) == 0 && Tools.match_psi_term(p1, p2)
    case (_, _) => false
  }

  def match_psi_term(x: PsiTerm, y: PsiTerm): Boolean = (x, y) match {
    case (foncteur(n1, t1), foncteur(n2, t2)) => n1.compareTo(n2) == 0 && Tools.match_tuple(t1, t2)
    case (psi_string(s1), psi_string(s2)) => s1.compareTo(s2) == 0
    case (psi_int(i1), psi_int(i2)) => i1 == i2
    case (_, psi_com_var(_)) => true
    case (_, _) => false
  }

  def fix_var(f: foncteur, s: Tuple): foncteur = f match {
  	case foncteur(n, t) => foncteur(n, Tools.fix(t,s))
  }

  def fix(t: Tuple, s:Tuple): Tuple = t match {
  	case complex_tuple(n, p, next) => {
  		Tools.get_value(s, n) match {
  			case null => complex_tuple(n, p, Tools.fix(next, s))
  			case x => complex_tuple(n, x, Tools.fix(next, s))
  		}
  	}
  	case simple_tuple(n, p) => {
  		Tools.get_value(s, n) match {
  			case null => simple_tuple(n, p)
  			case x => simple_tuple(n, x)
  		}
  	}
  }

  def extract_var(f1: foncteur, f2:foncteur, s: Tuple): Tuple =  (f1, f2) match {
  	case (foncteur(n1, t1), foncteur(n2, t2)) => Tools.extract(t1, t2, s)
  	case (_, _) => s
  }

  def extract(t1: Tuple, t2: Tuple, s:Tuple): Tuple = s match {
  	case complex_tuple(n, v, next) => {
  		Tools.get_value(t2, Tools.get_attribute(t1, n)) match {
  			case null => complex_tuple(n, v, Tools.extract(t1, t2, next))
  			case x => complex_tuple(n, x, Tools.extract(t1, t2, next))
  		}
  	}
  	case simple_tuple(n, v) => {
  		Tools.get_value(t2, Tools.get_attribute(t1, n)) match {
  			case null => simple_tuple(n, v)
  			case x => simple_tuple(n, x)
  		}
  	}
  	case _ => s
  }

  def get_attribute(t: Tuple, attr: String): String = t match {
  	case complex_tuple(n, p, next) => {
  		if(match_var(p,attr)) {Tools.assign(attr, n, next)}
  		else Tools.get_attribute(next, attr)
  	}
  	case simple_tuple(n, p) => {
  		if(match_var(p,attr)) {n}
  		else ""
  	}
  }

  def get_value(t: Tuple, attr: String): PsiTerm = t match {
  	case complex_tuple(n, p, next) => {
  		if(n.compareTo(attr) == 0) {p}
  		else Tools.get_value(next, attr)
  	}
  	case simple_tuple(n, p) => {
  		if(n.compareTo(attr) == 0) {p}
  		else null
  	}
  	case null => null
  }

  def match_var(p: PsiTerm, s: String) = p match {
  	case psi_string(n) => n.compareTo(s) == 0
  	case psi_com_var(n) => n.compareTo(s) == 0
  	case _ => false
  }

  def assign(s: String, attr: String, t: Tuple): String = t match {
    case complex_tuple(n, v, next) => {
      if(Tools.match_var(v, s)) {throw new Exception("Multiple assignement to a single communication variable.")}
      else assign(s, attr, next)
    }
    case simple_tuple(n, v) => {
      if(Tools.match_var(v, s)) {throw new Exception("Multiple assignement to a single communication variable.")}
      else attr
    }
  }
}

import scala.util.parsing.combinator._
import scala.util.matching.Regex

class BachTParsers extends RegexParsers {

  def name   : Parser[String] = ("[a-z][0-9a-zA-Z_]*").r ^^ {_.toString}
  def text   : Parser[String] = ("[a-zA-Z]+").r ^^ {_.toString}
  def number : Parser[Int] = ("0|[1-9][0-9]*").r ^^ {_.toString.toInt}

  def tellFoncteur   : Parser[foncteur] = name~"("~tellTupleSpace~")" ^^ {
    case vname ~ _ ~ vtupleSpace ~ _ => foncteur(vname, vtupleSpace)}
  def tellTupleSpace : Parser[Tuple] = tellPair~rep(",[ ]*".r~tellTupleSpace) ^^ {
    case p ~ List() => simple_tuple(p._1, p._2)
    case p ~ List(_ ~ pList) => complex_tuple(p._1, p._2, pList)
  }
  def tellPair       : Parser[Tuple2[String, PsiTerm]] = name~"[ ]*=[ ]*".r~tellPsiTerm ^^ {
    case vname ~ _ ~ vpsiTerm => (vname, vpsiTerm)}
  def tellPsiTerm    : Parser[PsiTerm] = tellFoncteur ^^ {
    case f => f}                     |
                                         name ^^ {
    case vname => psi_string(vname)} |
    									 text ^^ {
    case vname => psi_string(vname)} |
                                         number ^^ {
    case vint => psi_int(vint)}

  def askFoncteur   : Parser[foncteur] = name~"("~askTupleSpace~")" ^^ {
    case vname ~ _ ~ vtupleSpace ~ _ => foncteur(vname, vtupleSpace)}
  def askTupleSpace : Parser[Tuple] = askPair~rep(",[ ]*".r~askTupleSpace) ^^ {
    case p ~ List() => simple_tuple(p._1, p._2)
    case p ~ List(_ ~ pList) => complex_tuple(p._1, p._2, pList)
  }
  def askPair       : Parser[Tuple2[String, PsiTerm]] = name~"[ ]*=[ ]*".r~askPsiTerm ^^ {
    case vname ~ _ ~ vpsiTerm => (vname, vpsiTerm)}
  def askPsiTerm    : Parser[PsiTerm] = askFoncteur ^^ {
    case f => f}                     |
                                         name ^^ {
    case vname => psi_string(vname)} |
    									 text ^^ {
    case vname => psi_string(vname)} |
                                         number ^^ {
    case vint => psi_int(vint)}      |
                                         "?"~name ^^ {
    case _ ~ vname => psi_com_var(vname)}

  val opChoice  : Parser[String] = "+" 
  val opPara    : Parser[String] = "||"
  val opSeq     : Parser[String] = ";" 
 
  def primitive : Parser[Expr]   = "tell("~tellFoncteur~")" ^^ {
        case _ ~ vtoken ~ _  => bacht_ast_primitive("tell",vtoken) }  | 
                                   "ask("~askFoncteur~")" ^^ {
        case _ ~ vtoken ~ _  => bacht_ast_primitive("ask",vtoken) }   | 
                                   "get("~askFoncteur~")" ^^ {
        case _ ~ vtoken ~ _  => bacht_ast_primitive("get",vtoken) }   | 
                                   "nask("~askFoncteur~")" ^^ {
        case _ ~ vtoken ~ _  => bacht_ast_primitive("nask",vtoken) }

  def agent_with_var : Parser[(Expr, Tuple)] = agent ^^ {case ag => (ag, null)} |
                                               "local".r~varDec~"in".r~agent~"end".r ^^ {case _ ~ varDec ~ _ ~ ag ~ _ => (ag, varDec)}

  def agent : Parser[Expr] = compositionChoice

  def compositionChoice : Parser[Expr] = compositionPara~rep(opChoice~compositionChoice) ^^ {
        case ag ~ List() => ag
        case agi ~ List(op~agii)  => bacht_ast_agent(op,agi,agii) }

  def compositionPara : Parser[Expr] = compositionSeq~rep(opPara~compositionPara) ^^ {
        case ag ~ List() => ag
        case agi ~ List(op~agii)  => bacht_ast_agent(op,agi,agii) }

  def compositionSeq : Parser[Expr] = simpleAgent~rep(opSeq~compositionSeq) ^^ {
        case ag ~ List() => ag
        case agi ~ List(op~agii)  => bacht_ast_agent(op,agi,agii) }

  def simpleAgent : Parser[Expr] = primitive | parenthesizedAgent

  def parenthesizedAgent : Parser[Expr] = "("~>agent<~")"

  def varDec : Parser[Tuple] = name~rep(",".r~varDec) ^^ {
  	case p ~ List() => simple_tuple(p, null)
    case p ~ List(_ ~ pList) => complex_tuple(p, null, pList)
  }

}

object BachTSimulParser extends BachTParsers {

  def parse_primitive(prim: String) = parseAll(primitive,prim) match {
        case Success(result, _) => result
        case failure : NoSuccess => scala.sys.error(failure.msg)
  }

  def parse_agent(ag: String) = parseAll(agent_with_var,ag) match {
        case Success(result, _) => result
        case failure : NoSuccess => scala.sys.error(failure.msg)
  }

}

import scala.collection.mutable.Map
import scala.collection.mutable.ListBuffer
import scala.swing._

class BachTStore {

   var theStore = Map[String,ListBuffer[foncteur]]()

   def tell(token:foncteur):foncteur = {
      if (theStore.contains(token.name)) 
        { theStore(token.name) += token }
      else
        { theStore.put(token.name, new ListBuffer[foncteur])
          theStore(token.name) += token}
      token
   }


   def ask(token:foncteur):foncteur = {
      if (theStore.contains(token.name)) 
      {
        val t = theStore(token.name).find(x => Tools.match_psi_term(x, token)) match {
        	case Some(x) => x
        	case _ => null
        }
        t
      }
      else null
   }


   def get(token:foncteur):foncteur = {
      if (theStore.contains(token.name)) 
      {
        val t = theStore(token.name).find(x => Tools.match_psi_term(x, token)) match {
        	case Some(x) => x
        	case _ => null
        }
        if (t != null) {theStore(token.name) -= t}
        t
      }
      else null
   }


   def nask(token:foncteur):foncteur = ask(token)

   def print_store {
      println("Store: ")
      for ((t,d) <- theStore) 
         println ( t + "(" + theStore(t) + ")" )
      println()
   }

   def clear_store {
      theStore = Map[String,ListBuffer[foncteur]]()
   }

}

object bb extends BachTStore {

   def reset { clear_store }

}

import scala.util.Random
import language.postfixOps

class BachTSimul(var bb: BachTStore) {

   val bacht_random_choice = new Random()

   def run_one(agent: Expr, store: Tuple):(Boolean,Expr,Tuple) = {

      agent match {
         case bacht_ast_primitive(prim,token) => 
            {  
            	val result = exec_primitive(prim, token, store)
            	if(result._1) {(true, bacht_ast_empty_agent(), result._2)}
            	else (false, agent, store)
            }

         case bacht_ast_agent(";",ag_i,ag_ii) =>
            {  run_one(ag_i,store) match
                  { case (false,_,_) => (false,agent,store)
                    case (true,bacht_ast_empty_agent(),s) => (true,ag_ii,s)                 
                    case (true,ag_cont,s) => (true,bacht_ast_agent(";",ag_cont,ag_ii),s)
                  }
            }

         case bacht_ast_agent("||",ag_i,ag_ii) =>
            {  var branch_choice = bacht_random_choice.nextInt(2) 
               if (branch_choice == 0) 
                 { run_one(ag_i,store) match
                      { case (false,_,_) => 
                          { run_one(ag_ii,store) match
                              { case (false,_,_)
                                  => (false,agent,store)
                                case (true,bacht_ast_empty_agent(),s)
                                  => (true,ag_i,s)                 
                                case (true,ag_cont,s)
                                  => (true,bacht_ast_agent("||",ag_i,ag_cont),s)
                              }
                          }
                        case (true,bacht_ast_empty_agent(),s)
                                  => (true,ag_ii,s)                 
                        case (true,ag_cont,s) 
                                  => (true,bacht_ast_agent("||",ag_cont,ag_ii),s)
                      }
                  }
               else
                 { run_one(ag_ii,store) match
                      { case (false,_,_) => 
                          { run_one(ag_i,store) match
                              { case (false,_,_) => (false,agent,store)
                                case (true,bacht_ast_empty_agent(),s) => (true,ag_ii,s)                 
                                case (true,ag_cont,s)
                                      => (true,bacht_ast_agent("||",ag_cont,ag_ii),s)
                              }
                          }
                        case (true,bacht_ast_empty_agent(),s) 
                          => (true,ag_i,s)                 
                        case (true,ag_cont,s)
                          => (true,bacht_ast_agent("||",ag_i,ag_cont),s)
                      }
                  }
             
            }


         case bacht_ast_agent("+",ag_i,ag_ii) =>
            {  var branch_choice = bacht_random_choice.nextInt(2) 
               if (branch_choice == 0) 
                 { run_one(ag_i,store) match
                      { case (false,_,_) => 
                          { run_one(ag_ii,store) match
                              { case (false,_,_) => (false,agent,store)
                                case (true,bacht_ast_empty_agent(),s)
                                  => (true,bacht_ast_empty_agent(),s)                 
                                case (true,ag_cont,s)
                                  => (true,ag_cont,s)
                              }
                          }
                        case (true,bacht_ast_empty_agent(),s)
                          => (true,bacht_ast_empty_agent(),s)                 
                        case (true,ag_cont,s) 
                          => (true,ag_cont,s)
                      }
                  }
               else
                 { run_one(ag_ii,store) match
                      { case (false,_,_) => 
                          { run_one(ag_i,store) match
                              { case (false,_,_) 
                                  => (false,agent,store)
                                case (true,bacht_ast_empty_agent(),s)
                                  => (true,bacht_ast_empty_agent(),s)                 
                                case (true,ag_cont,s)
                                  => (true,ag_cont,s)
                              }
                          }
                        case (true,bacht_ast_empty_agent(),s)
                          => (true,bacht_ast_empty_agent(),s)                 
                        case (true,ag_cont,s)
                          => (true,ag_cont,s)
                      }
                  }
            }
      }
   }

   def bacht_exec_all(agent: Expr, store: Tuple):Boolean = {

       var failure = false
       var c_agent = agent
       var c_store = store
       while ( c_agent != bacht_ast_empty_agent() && !failure ) {
          failure = run_one(c_agent, c_store) match 
               { case (false,_,_)          => true
                 case (true,new_agent,new_store)  => 
                    { c_agent = new_agent
                      c_store = new_store
                      false
                    }
               }
           bb.print_store
           println("Variables:")
           println(c_store)
           println("\n")
       }
       
       if (c_agent == bacht_ast_empty_agent()) {
           println("Success\n")
           bb.clear_store
           true
       }
       else {
           println("failure\n")
           bb.clear_store
           false
       }
   }  

   def exec_primitive(prim: String, token: foncteur, store: Tuple):(Boolean, Tuple) = {
       prim match
         { case "tell" => {
         	val t = bb.tell(Tools.fix_var(token, store))
         	(true, store)
         }
           case "ask"  => {
           	val t = bb.ask(Tools.fix_var(token, store))
           	val s = Tools.extract_var(token, t, store)
           	(t != null, s)
           }
           case "get"  => {
           	val t = bb.get(Tools.fix_var(token, store))
           	val s = Tools.extract_var(token, t, store)
           	(t != null, s)
           }
           case "nask" => {
           	val t = bb.nask(Tools.fix_var(token, store))
           	val s = Tools.extract_var(token, t, store)
           	(t == null, s)
           }
         }
   }

}


object ag extends BachTSimul(bb) {

  def apply(agent: String) {
     val agent_parsed = BachTSimulParser.parse_agent(agent)
     ag.bacht_exec_all(agent_parsed._1, agent_parsed._2)
  }
  def eval(agent:String) { apply(agent) }
  def run(agent:String) { apply(agent) }

  def main(args: Array[String]): Unit = {
  	println("Bienvenu dans l'interpreteur BachT avec l'intégration des psi-termes.")
  	println("Entrer une expression à évaluer pour utiliser l'interpreteur ou quit pour quitter l'application.")
  	println()
  	print("BachT > ")
  	var input = scala.io.StdIn.readLine()
  	while (input.compareToIgnoreCase("exit") != 0)
  	{
  		try{
  			ag run input
  		}
  		catch{
  			case e:Exception => {
  				println()
  				println("Un problème a été rencontré lors du traitement de l'expression.")
  				println("Voulez-vous voir la trace générée par l'erreur? [Y/n]")
  				input = scala.io.StdIn.readLine()
  				if(input.compareToIgnoreCase("y") == 0 || input.compareToIgnoreCase("yes") == 0) {
  					println(e)
  					println()
  					e
  				}
  			}
  		}
  		print("BachT > ")
  		input = scala.io.StdIn.readLine()
  	}
  }

}

This snippet took 0.03 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).