isac-java/src/java/isac/gui/mawen/scalaterm/Util.scala
author Natalie Karl <S1420454023@students.fh-hagenberg.at>
Thu, 30 Jun 2016 18:29:31 +0200
changeset 4925 b0adbcc94847
parent 4924 d1ad1bd88f1b
child 4932 70274849b169
permissions -rw-r--r--
TermTree has a soundmodel
wneuper@4856
     1
package isac.gui.mawen.scalaterm
wneuper@4856
     2
S1420454023@4913
     3
import isac.gui.mawen.termtree.TreeNodeContent
wneuper@4907
     4
import javax.swing.tree.DefaultMutableTreeNode
wneuper@4900
     5
wneuper@4859
     6
import edu.tum.cs.isabelle.api.XML
wneuper@4856
     7
import edu.tum.cs.isabelle.pure._
wneuper@4859
     8
import edu.tum.cs.isabelle._      // for Codec
wneuper@4856
     9
wneuper@4856
    10
object Util {
wneuper@4856
    11
wneuper@4856
    12
  def int(s: String): Integer = new Integer(s)
wneuper@4856
    13
  
wneuper@4856
    14
 /* Data for presentation of Const which are not contained in (Scala-) Term:
wneuper@4856
    15
  * _1: string as shown by Isabelle's pretty printing
wneuper@4856
    16
  * _2: string in LaTeX format with place-holders "#d", where d is a digit:
wneuper@4856
    17
  *     number of place-holders determine arity;
wneuper@4856
    18
  *     pre/post/mix-fix is read out from here also for _1
wneuper@4856
    19
  * _3: infixl | infixr | prefix | postfix: the latter two are redundant with _2
wneuper@4856
    20
  * _4: priority, which determines parentheses to be set
wneuper@4856
    21
  * TODO: reconsider data representation: record, ...
wneuper@4856
    22
  */
wneuper@4856
    23
  val present = Map (
wneuper@4856
    24
    "HOL.eq" -> (" = ", "#1=#2", "infixl", 50),                              //see ~~/src/HOL/HOL.thy
wneuper@4856
    25
    "Groups.plus_class.plus" -> (" + ", "#1+#2", "infixl", 65),              //see ~~/src/HOL/Groups.thy
wneuper@4856
    26
    "Groups.plus_class.minus" -> (" - ", "#1-#2", "infixl", 65),             //see ~~/src/HOL/Groups.thy
wneuper@4856
    27
    "Groups.plus_class.uminus" -> (" -", "#1-#2", "prefix", 80),             //see ~~/src/HOL/Groups.thy
wneuper@4856
    28
    "Groups.times_class.times" -> (" * ", "#1.#2", "infixl", 70),            //see ~~/src/HOL/Groups.thy
wneuper@4856
    29
    //"Groups.plus_class.times"->("*", "#1\cdot#2", "infixl", 70),
wneuper@4856
    30
    //...ERROR: implicit conversion found: Groups.plus_class.times => ...
wneuper@4867
    31
    "Fields.inverse_class.divide" -> (" / ", "\frac{#1}{#2}", "infixl", 70), //see ~~/src/HOL/Fields.thy
wneuper@4856
    32
    "Power.power_class.power" -> (" ^ ", "#1^{#2}", "infixr", 80)            //see ~~/src/HOL/Transcendental.thy
wneuper@4856
    33
    //"Transcendental.sin" -> ("sin ", "\sin{#1}", "infixl", 70)
wneuper@4856
    34
    //...ERROR: implicit conversion found: ...
wneuper@4856
    35
    )
wneuper@4856
    36
  /* so not every constant needs to be in Util.present */
wneuper@4856
    37
  def ST_isa(str: String): String = {
wneuper@4856
    38
    present.get(str) match {
wneuper@4856
    39
      case Some((isa, _, _, _)) => isa 
wneuper@4856
    40
      case None => str.substring(str.lastIndexOf(".") + 1) + " "}}
wneuper@4856
    41
  def ST_latex(str: String): String = {
wneuper@4856
    42
    present.get(str) match {
wneuper@4856
    43
      case Some((_, latex, _, _)) => latex 
wneuper@4856
    44
      case None => str.substring(str.lastIndexOf(".") + 1) + " "}}
wneuper@4856
    45
  def ST_fix(str: String): String = {
wneuper@4856
    46
    present.get(str) match {
wneuper@4856
    47
      case Some((_, _, fix, _)) => fix 
wneuper@4856
    48
      case None => "prefix"}}
wneuper@4856
    49
  def ST_prior(str: String): Int = {
wneuper@4856
    50
    present.get(str) match {
wneuper@4856
    51
      case Some((_, _, _, prior)) => prior 
wneuper@4856
    52
      case None => 99}}
wneuper@4856
    53
  
wneuper@4856
    54
  /* transform a Term into a String, which corresponds to Isabelle's 
wneuper@4856
    55
   * pretty_printing within Isac's Knowledge.
wneuper@4856
    56
   * mawen uses this for string representation of Terms.
wneuper@4856
    57
   */
wneuper@4857
    58
  def str_of(t: Term, prior: Int, l_r: String): String = t match {
wneuper@4856
    59
    case App(App(Const("Product_Type.Pair", _), t1), t2) 
wneuper@4857
    60
    => str_of(t1, prior, "none") + ", " + str_of(t2, prior, "none")
wneuper@4856
    61
    case App(App(Const(str, _), t1), t2) 
wneuper@4856
    62
    => { val pri = ST_prior(str)
wneuper@4856
    63
      if (prior > pri) {
wneuper@4856
    64
         ST_fix(str) match {
wneuper@4857
    65
         case "infixl" => "(" + str_of(t1, pri, "left") + ST_isa(str) + str_of(t2, pri, "right") + ")"
wneuper@4857
    66
         case "infixr" => "(" + str_of(t1, pri, "left") + ST_isa(str) + str_of(t2, pri, "right") + ")"
wneuper@4857
    67
         case "prefix" => "(" + ST_isa(str) + str_of(t1, pri, "left") + " (2" + str_of(t2, pri, "right") + "2)" + ")"}
wneuper@4856
    68
      }else{
wneuper@4856
    69
         ST_fix(str) match {
wneuper@4856
    70
         case "infixl" => {
wneuper@4857
    71
           if (prior == pri & l_r == "right") {
wneuper@4857
    72
             "(" + str_of(t1, pri, "left") + ST_isa(str) + str_of(t2, pri, "right") + ")"
wneuper@4857
    73
           }else{
wneuper@4857
    74
             str_of(t1, pri, "left") + ST_isa(str) + str_of(t2, pri, "right")
wneuper@4856
    75
           }
wneuper@4857
    76
         }
wneuper@4857
    77
         case "infixr" => {
wneuper@4857
    78
           if (prior == pri & l_r == "left") {
wneuper@4857
    79
             "(" + str_of(t1, pri, "left") + ST_isa(str) + str_of(t2, pri, "right") + ")"
wneuper@4857
    80
           }else{
wneuper@4857
    81
             str_of(t1, pri, "left") + ST_isa(str) + str_of(t2, pri, "right")
wneuper@4857
    82
           }
wneuper@4857
    83
         }
wneuper@4857
    84
         case "prefix" => ST_isa(str) + str_of(t1, pri, "none") + " " + str_of(t2, pri, "none")}
wneuper@4856
    85
      }}
wneuper@4857
    86
    case App(Const(str, _), t1) => ST_isa(str) + "(" + str_of(t1, prior, "none") + ")"
wneuper@4857
    87
    case Free(str, _) =>  str
wneuper@4856
    88
    case Const(str, _) => str
wneuper@4856
    89
    case _ => throw new IllegalArgumentException("str_of WRONG arg: " + t)
wneuper@4856
    90
  }
wneuper@4857
    91
  // infix: "left" or "right" argument ----------vvvv
wneuper@4857
    92
  def string_of(t: Term): String = str_of(t, 0, "none")
wneuper@4859
    93
  
wneuper@4859
    94
  def wrap_term (t: Term): XML.Tree =
wneuper@4859
    95
    XML.Elem(("MATHML", Nil), List(
wneuper@4859
    96
      XML.Elem(("ISA", Nil), List(XML.Text("aaa + bbb::real"))),
wneuper@4859
    97
      XML.Elem(("TERM", Nil), List(Codec[Term].encode(t)))))
wneuper@4897
    98
      
wneuper@4907
    99
  def insert_nodes(t: Term, n: DefaultMutableTreeNode): DefaultMutableTreeNode = t match {
wneuper@4900
   100
    case App(App(Const("Product_Type.Pair", _), t1), t2) 
wneuper@4908
   101
    => n //TODO
S1420454023@4913
   102
    case App(App(Const(str, typ), t1), t2)
S1420454023@4913
   103
    => { val tmp1 = n.clone().asInstanceOf[DefaultMutableTreeNode]
S1420454023@4913
   104
         n.setUserObject(new TreeNodeContent(ST_isa(str), Util.string_of(App(App(Const(str, typ), t1), t2))))
S1420454023@4913
   105
         n.add(insert_nodes(t1, tmp1))
S1420454023@4913
   106
         val tmp2 = n.clone().asInstanceOf[DefaultMutableTreeNode]
S1420454023@4913
   107
         n.add(insert_nodes(t2, tmp2))
wneuper@4907
   108
         n 
wneuper@4907
   109
      }
S1420454023@4913
   110
    case App(Const(str, typ), t1) 
wneuper@4907
   111
    => { val tmp = n.clone().asInstanceOf[DefaultMutableTreeNode]
S1420454023@4913
   112
         n.setUserObject(new TreeNodeContent(ST_isa(str), Util.string_of(App(Const(str, typ), t1))))
wneuper@4907
   113
         n.add(insert_nodes(t1, tmp))
wneuper@4907
   114
         n 
wneuper@4907
   115
      }
wneuper@4907
   116
    case Free(str, _) => { n.setUserObject(str); n }
wneuper@4907
   117
    case Const(str, _) => { n.setUserObject(str); n }
wneuper@4900
   118
    case _ => throw new IllegalArgumentException("jtree_of WRONG arg: " + t)
wneuper@4900
   119
  }
wneuper@4907
   120
  def jtree_of(t: Term): DefaultMutableTreeNode = insert_nodes(t, new DefaultMutableTreeNode)
S1420454023@4925
   121
  
wneuper@4923
   122
  def sound_of_sub(t: Term, line: Integer, indent: Integer): Unit = t match {
wneuper@4923
   123
    case App(App(Const("Product_Type.Pair", _), t1), t2) 
S1420454023@4925
   124
    => isac.gui.mawen.SoundUtils.tone(261, 500)
wneuper@4923
   125
    case App(App(Const(str, typ), t1), t2)
S1420454023@4925
   126
    => { isac.gui.mawen.SoundUtils.repeatTone(261+(10*line), 500,indent) //tonhoehe: line, wiederholung: intent
wneuper@4923
   127
         sound_of_sub(t1, line + 1, indent + 1)
wneuper@4923
   128
         sound_of_sub(t2, line + 1, indent + 1)
wneuper@4923
   129
      }
wneuper@4923
   130
    case App(Const(str, typ), t1) 
S1420454023@4925
   131
    => { isac.gui.mawen.SoundUtils.repeatTone(261+(10*line), 500,indent) //tonhoehe: line, wiederholung: intent
wneuper@4923
   132
         sound_of_sub(t1, line + 1, indent + 1)
wneuper@4923
   133
      }
wneuper@4923
   134
    case Free(str, _) => { 
S1420454023@4925
   135
       isac.gui.mawen.SoundUtils.repeatTone(1000+(10*line), 500,indent)
wneuper@4923
   136
      }
wneuper@4923
   137
    case Const(str, _) => { 
S1420454023@4925
   138
       isac.gui.mawen.SoundUtils.repeatTone(2000+(10*line), 500,indent)
wneuper@4923
   139
      }
wneuper@4923
   140
    case _ => throw new IllegalArgumentException("sound_of WRONG arg: " + t)
wneuper@4923
   141
  }
wneuper@4923
   142
  def sound_of(t: Term) = sound_of_sub(t, 0, 0)
wneuper@4923
   143
wneuper@4923
   144
  
wneuper@4920
   145
  def is_numeral(s: String): Boolean = {
wneuper@4920
   146
    try {
wneuper@4920
   147
      s.toInt; true
wneuper@4920
   148
    } catch {
wneuper@4920
   149
      case e: Exception => false
wneuper@4920
   150
    }
wneuper@4920
   151
  }
wneuper@4920
   152
  def matml_of(t: Term, prior: Int, l_r: String): String = t match {
wneuper@4920
   153
    case App(App(Const("Product_Type.Pair", _), t1), t2) 
wneuper@4920
   154
    => matml_of(t1, prior, "none") + ", " + matml_of(t2, prior, "none")
wneuper@4920
   155
    case App(App(Const("Fields.inverse_class.divide", _), t1), t2) 
wneuper@4920
   156
    => { 
wneuper@4920
   157
      val str = "Fields.inverse_class.divide"
wneuper@4920
   158
      val pri = ST_prior(str)
wneuper@4920
   159
      "<mfrac><mrow>" + matml_of(t1, pri, "left") + "</mrow><mrow>" + matml_of(t2, pri, "right") + "</mrow></mfrac>"
wneuper@4920
   160
    }
wneuper@4920
   161
    case App(App(Const(str, _), t1), t2) 
wneuper@4920
   162
    => { val pri = ST_prior(str)
wneuper@4920
   163
      if (prior > pri) {
wneuper@4920
   164
         ST_fix(str) match {
wneuper@4920
   165
         case "prefix" => "<mfenced separators=\'\'>" + "<mo>" + ST_isa(str) + "</mo>" + matml_of(t1, pri, "left") + 
wneuper@4920
   166
           "<mfenced separators=\'\'>" + matml_of(t2, pri, "right") + "</mfenced>" + "</mfenced>"
wneuper@4920
   167
         case _ => "<mfenced separators=\'\'>" + matml_of(t1, pri, "left") + "<mo>" + 
wneuper@4920
   168
           ST_isa(str) + "</mo>" + matml_of(t2, pri, "right") + "</mfenced>"
wneuper@4920
   169
         }
wneuper@4920
   170
      }else{
wneuper@4920
   171
         ST_fix(str) match {
wneuper@4920
   172
         case "prefix" => "<mo>" + ST_isa(str) + "</mo>" + matml_of(t1, pri, "none") + " " + matml_of(t2, pri, "none")
wneuper@4920
   173
         case _ => {
wneuper@4920
   174
           if (prior == pri & l_r == "right") {
S1420454023@4922
   175
             matml_of(t1, pri, "left") + "<mo>" + ST_isa(str) + "</mo>" + matml_of(t2, pri, "right")
wneuper@4920
   176
           }else{
wneuper@4920
   177
             matml_of(t1, pri, "left") + "<mo>" + ST_isa(str) + "</mo>" + matml_of(t2, pri, "right")
wneuper@4920
   178
           }
wneuper@4920
   179
         }}
wneuper@4920
   180
      }
wneuper@4920
   181
    }
wneuper@4920
   182
    case App(Const(str, _), t1) => "<mo>" + ST_isa(str) + "</mo>" + "<mfenced separators=\'\'>" + matml_of(t1, prior, "none") + "</mfenced>"
wneuper@4920
   183
    case Free(str, _) => if (is_numeral(str)) "<mn>" + str + "</mn>" else "<mi>" + str + "</mi>"
wneuper@4920
   184
    case Const(str, _) => str
wneuper@4920
   185
    case _ => throw new IllegalArgumentException("matml_of WRONG arg: " + t)
wneuper@4920
   186
  }
S1420454023@4922
   187
  def mathml_of(t: Term): String = "<math xmlns="+"\"&mathml;\""+"><mrow>" + matml_of(t, 0, "none") + "</mrow></math>"
wneuper@4920
   188
  
wneuper@4856
   189
}