Element.scala
author Chengsong
Fri, 15 Mar 2019 12:27:12 +0000
changeset 4 7a349fe58bf4
parent 0 902326e1615a
permissions -rwxr-xr-x
:test whether bsimp(bders(r, s)) == ders_simp(r,s) This does not hold. As illustrated by the output of the example where string is abaa and regex is (a* + ab)* this property still holds when s = aba but after the derivative of the last character a, the result is negative. However this seems easily fixable as the difference is relatively small, it might be possible to find where the difference happens and by taking that difference into accound we have some function f s.t. f(bsimp(r,s)) = ders_simp(r,s) and mkeps(f(r)) = mkeps(r) This will complete the correctness proof. Even if finding such f is hard, it would still provide insights for the real difference between simp(der(simp(der(simp(der...... and simp(ders

import Element.elem
abstract class Element{
  def contents: Array[String]

  def height: Int = contents.length
  def width: Int = contents(0).length

  

  def above(that: Element): Element = {
    //new ArrayElement(this.contents ++ that.contents)
    val this1 = this widen that.width
    val that1 = that widen this.width
    elem(this1.contents ++ that1.contents)
  }
  def left_align(that: Element): Element = {
    if (this.width == that.width){
      this above that
    }
    else if (this.width < that.width) {
      (this beside elem(' ', that.width - this.width, this.height)) above that
    }
    else {
      this above (that beside elem(' ', this.width - that.width, that.height))
    }
  }
  def up_align(that: Element): Element = {
    if (this.height == that.height){
      this beside that
    }
    else if (this.height < that.height) {
      (this above elem(' ', this.width, that.height - this.height)) beside that
    }
    else {
      this beside (that above elem(' ', that.width, this.height - that.height))
    }  
  }
  def beside(that: Element): Element = {
    val this1 = this heighten that.height
    val that1 = that heighten this.height
    elem(
      for ((line1, line2) <- this1.contents zip that1.contents)
      yield line1 + line2)
  }
  def widen(w: Int): Element = 
    if(w <= width) this
    else {
      val left = Element.elem(' ', (w - width) / 2, height)
      var right = Element.elem(' ', w - width - left.width, height)
      left beside this beside right
    }
  def heighten(h: Int): Element = 
    if (h <= height) this
    else {
      val top = Element.elem(' ', width, (h - height) / 2)
      val bot = Element.elem(' ', width, h - height - top.height)
      top above this above bot
    }
  override def toString = contents mkString "\n"
}
object Element {
  private class ArrayElement(
    val contents: Array[String]
  ) extends Element

  private class LineElement(s: String) extends Element {
    val contents = Array(s)
    override def width = s.length
    override def height = 1
  }

  private class UniformElement(
    ch: Char,
    override val width: Int,
    override val height: Int
  ) extends Element {
    private val line = ch.toString * width
    def contents = Array.fill(height)(line)
  }

  def elem(contents: Array[String]): Element =
    new ArrayElement(contents)
    
  def elem(chr: Char, width: Int, height: Int): Element =
    new UniformElement(chr, width, height)
    
  def elem(line: String): Element =
      new LineElement(line)
}