Zulip Chat Archive

Stream: new members

Topic: Help with proof structure


HenrikT (Jun 01 2023 at 21:02):

Hi everyone,
i am currently using Lean4 and created the following definitions:

import Mathlib.Data.Set.Basic
import Mathlib.Data.Set.Countable
import Mathlib.Data.Finset.Basic
import Mathlib.Data.List.Basic

inductive Direction where
  | L : Direction
  | R : Direction
  | N : Direction


def directionToNum (d : Direction) :  :=
  match d with
  | Direction.L => -1
  | Direction.R => 0
  | Direction.N => 1


structure Cfg where
  state : 
  head : 
  left : List 
  right : List 

structure Machine where
  Q : Finset 
  Λ : Finset 
  Γ : Finset 
  Fₐ : Finset 
  F : Finset 
  q0 : 
  δ : Finset ( ×    ×  × Direction)

structure DTM  extends Machine where

  uniqueness:
     x y : ( ×    ×  × Direction),
       (a₁ a₂ : ( × )), a₁ = a₂  x a₁ = y a₂


def cfgEquiv (c1 c2 : Cfg) : Prop :=
  c1.state = c2.state  c1.head = c2.head  c1.left = c2.left  c1.right = c2.right

def updateHead (n: ) (d: Direction) :  :=
  match n, d with
    | 0, Direction.L => 0
    | _, Direction.R => n+1
    | _, Direction.L => n-1
    | _, Direction.N => n

def updateCfg (cfg: Cfg) (s w : ) (d: Direction) : Cfg :=
  match cfg.head, d with
    | 0, Direction.L => {state := s, head := 0, left := List.nil,  right := cfg.right.modifyHead w}
    | _, Direction.L => {state := s, head := cfg.head-1, left := cfg.left.reverse.tail.reverse,  right := [w].append cfg.left}
    | _, Direction.R => {state := s, head := cfg.head+1, left := cfg.left.append [w],  right := cfg.left.tail}
    | _, Direction.N => {state := s, head := cfg.head, left := cfg.left,  right := cfg.right.modifyHead w}


def reachSucc (M : Machine) (c1 c2 : Cfg) : Prop :=
   (a γ s w : ) (d : Direction),  δ  M.δ, δ (a, γ) = (s, w, d)  cfgEquiv (updateCfg c1 s w d) c2

def isAccept (M : Machine) (cfg : Cfg)  : Prop :=
  cfg.state  M.Fₐ

def isReject (M : Machine) (cfg : Cfg)  : Prop :=
  cfg.state  M.F

def isFinal (M : Machine) (cfg : Cfg)  : Prop :=
  cfg.state  M.Fₐ  cfg.state  M.F

def reachN (M : Machine) (n : ) (c1 c2 : Cfg) : Prop :=
  if n = 0 then cfgEquiv c1 c2
  else if n = 1 then reachSucc M c1 c2
  else  (c3 : Cfg), reachN M (n-1) c1 c3  reachN M (n-1) c3 c2


def finiteReach (M : Machine) (c1 c2 : Cfg) : Prop :=
   (n : ), reachN M n c1 c2

def Word := List 

def Word.concat (v w : Word) : Word := List.append v w
infixr:50 " + " => Word.concat

def Word.len (w: Word) :  :=
  w.length

def Language := Set Word

def Language.element (w : Word) (L : Set Word) : Prop := L w
infixr:75 " ∈ " => Language.element

def Language.complement (L : Language) : Language := λ w => ¬ (w  L)

def Language.notElement (w : Word) (L : Language) : Prop := L w
infixr: 75 "∉" => Language.notElement

def isDecider (M : Machine) : Prop :=
   (w : Word),  (c1 c2 : Cfg), c1 = {state := 0, head := 0, left := List.nil,  right := w} 
    finiteReach M c1 c2


def isEnumerator (M : Machine) (L : Language) : Prop :=
   (w : Word), w  L   (c1 c2 : Cfg), c1 = {state := 0, head := 0, left := List.nil,  right := w} 
    isAccept M c2  finiteReach M c1 c2


def isSemiDecider (M : Machine) : Prop :=
   (w : Word),  (c1 c2 : Cfg), c1 = {state := 0, head := 0, left := List.nil,  right := w} 
    isAccept M c2  finiteReach M c1 c2

def isCoSemiDecider (M : Machine) : Prop :=
   (w : Word),  (c1 c2 : Cfg), c1 = {state := 0, head := 0, left := List.nil,  right := w} 
    isReject M c2  finiteReach M c1 c2


def semi_decidable (L : Language) : Prop :=
   (M : Machine),  (w : Word),  (c1 c2 : Cfg),
    (w  L  c1 = {state := 0, head := 0, left := List.nil,  right := w}  finiteReach M c1 c2  isAccept M c2)

def co_semi_decidable (L : Language) : Prop :=
   (M : Machine),  (w : Word),  (c1 c2 : Cfg),
    (w  L  c1 = {state := 0, head := 0, left := List.nil,  right := w}  finiteReach M c1 c2  isReject M c2)

def decidable (L : Language) : Prop :=
   (M : Machine),  (w : Word),  (c1 c2 : Cfg),
    ((w  L  c1 = {state := 0, head := 0, left := List.nil,  right := w}  finiteReach M c1 c2  isAccept M c2) 
    (w  L  c1 = {state := 0, head := 0, left := List.nil,  right := w}  finiteReach M c1 c2  isReject M c2))

I then defined the following Theorem

theorem CoSemiAndSemiEqDescidable (L : Language) : decidable L  (semi_decidable L  co_semi_decidable L) :=
    sorry

Because i am pretty new to this i do not know how to proof this using Lean4.
I started by creating two goal (one for each direction) using apply Iff.intro then unfolded my definitions but then got more or less stuck.
Any idea on how to proceed ?

Thanks in advance :)

Martin Dvořák (Jun 01 2023 at 21:11):

Please provide imports.
#mwe

HenrikT (Jun 01 2023 at 21:13):

import Mathlib.Data.Set.Basic
import Mathlib.Data.Set.List
import Mathlib.Data.Finset.Basic
import Mathlib.Data.List.Basic


def Word := List 
def Language := Set Word


structure Cfg where
  state : 
  head : 
  left : List 
  right : List 

structure Machine where
  Q : Finset 
  Λ : Finset 
  Γ : Finset 
  Fₐ : Finset 
  F : Finset 
  q0 : 
  δ : Finset ( ×    ×  × Direction)

Martin Dvořák (Jun 01 2023 at 21:18):

Where is finiteReach defined?

HenrikT (Jun 01 2023 at 21:21):

I defined it in the same file. I was not sure how much code i should post.

the definitions look as follows:

inductive Direction where
  | L : Direction
  | R : Direction
  | N : Direction

def cfgEquiv (c1 c2 : Cfg) : Prop :=
  c1.state = c2.state  c1.head = c2.head  c1.left = c2.left  c1.right = c2.right

def reachSucc (M : Machine) (c1 c2 : Cfg) : Prop :=
   (a γ s w : ) (d : Direction),  δ  M.δ, δ (a, γ) = (s, w, d)  cfgEquiv (updateCfg c1 s w d) c2

def isAccept (M : Machine) (cfg : Cfg)  : Prop :=
  cfg.state  M.Fₐ

def isReject (M : Machine) (cfg : Cfg)  : Prop :=
  cfg.state  M.F

def isFinal (M : Machine) (cfg : Cfg)  : Prop :=
  cfg.state  M.Fₐ  cfg.state  M.F

def reachN (M : Machine) (n : ) (c1 c2 : Cfg) : Prop :=
  if n = 0 then cfgEquiv c1 c2
  else if n = 1 then reachSucc M c1 c2
  else  (c3 : Cfg), reachN M (n-1) c1 c3  reachN M (n-1) c3 c2


def finiteReach (M : Machine) (c1 c2 : Cfg) : Prop :=
   (n : ), reachN M n c1 c2

Martin Dvořák (Jun 01 2023 at 21:22):

You should post as much code as we need to replicate your issue.
#mwe

Martin Dvořák (Jun 01 2023 at 21:23):

Where is updateCfg defined?

HenrikT (Jun 01 2023 at 21:24):

def updateCfg (cfg: Cfg) (s w : ) (d: Direction) : Cfg :=
  match cfg.head, d with
    | 0, Direction.L => {state := s, head := 0, left := List.nil,  right := cfg.right.modifyHead w}
    | _, Direction.L => {state := s, head := cfg.head-1, left := cfg.left.reverse.tail.reverse,  right := [w].append cfg.left}
    | _, Direction.R => {state := s, head := cfg.head+1, left := cfg.left.append [w],  right := cfg.left.tail}
    | _, Direction.N => {state := s, head := cfg.head, left := cfg.left,  right := cfg.right.modifyHead w}

Martin Dvořák (Jun 01 2023 at 21:25):

#mwe
"so others can simply just cut and paste what you post, and see the same issue that you are seeing"

HenrikT (Jun 01 2023 at 21:27):

for the language i also defined the following

def Language.element (w : Word) (L : Set Word) : Prop := L w
infixr:75 " ∈ " => Language.element

-- failed to synth. instance membership Word Language ?
def Language.complement (L : Language) : Language := λ w => ¬ (w  L)

def Language.notElement (w : Word) (L : Language) : Prop := L w
infixr: 75 "∉" => Language.notElement

Martin Dvořák (Jun 01 2023 at 21:28):

Please click on the blue thing #mwe and follow the instructions.

HenrikT (Jun 01 2023 at 21:29):

ok i keep that in mind for next time, sorry for the confusion :)

Martin Dvořák (Jun 01 2023 at 21:32):

For the next time and for this time as well. Please. Give me a code that I can compile.

In case you don't want to copypaste too many lines of code, you can provide a link to a repository instead. However, I am fine with copypasting a long block of code IF IT WORKS.

Notification Bot (Jun 01 2023 at 21:33):

HenrikT has marked this topic as resolved.

Notification Bot (Jun 01 2023 at 21:34):

HenrikT has marked this topic as unresolved.

Martin Dvořák (Jun 01 2023 at 21:35):

Ah. You updated the original post! I'll have a look at it.

HenrikT (Jun 01 2023 at 21:37):

yes thanks for your patience. The problem is, that i used two files instead of one hence its a bit difficulty with just copy past. I hope it works now though :)

Martin Dvořák (Jun 01 2023 at 21:43):

This is how you can prove one of the "trivial" parts:

theorem CoSemiAndSemiEqDescidable (L : Language) : decidable L  (semi_decidable L  co_semi_decidable L) := by
  constructor
  · intro M, hM
    constructor
    · unfold semi_decidable
      use M
      intro w
      specialize hM w
      rcases hM with c₁, c₂, h_yesin, h_notin
      use c₁
      use c₂
      exact h_yesin
    · sorry
  · sorry

I suggest you play with it yourself and let us know when you encounter a major obstacle.

HenrikT (Jun 01 2023 at 21:45):

ok thanks a lot ill have a look at it

Martin Dvořák (Jun 01 2023 at 21:45):

Discharging the first sorry is straightforward. However, for the second implication, you will have to construct a new machine, which will be much more difficult.

Martin Dvořák (Jun 01 2023 at 21:48):

Note that in the part I provided "nothing" happens — I just took the assumption and threw away one part.

Martin Dvořák (Jun 01 2023 at 21:53):

This is not really educational but possibly useful:

theorem DecidableIff (L : Language) : decidable L  (semi_decidable L  co_semi_decidable L) := by
  constructor
  · intro M, hM
    constructor <;> use M <;> intro w <;> rcases hM w with c₁, c₂, w_yesin, w_notin
    · exact c₁, c₂, w_yesin
    · exact c₁, c₂, w_notin
  · sorry

HenrikT (Jun 01 2023 at 21:55):

thanks having an example to look at realy helps with understanding how Lean works

Martin Dvořák (Jun 01 2023 at 21:55):

If I can give a general advice, write more definitions and avoid stuff like:

{state := s, head := 0, left := List.nil,  right := cfg.right.modifyHead w}

HenrikT (Jun 01 2023 at 21:56):

ok ill try to keep that in mind

Martin Dvořák (Jun 01 2023 at 21:57):

If the issue is understanding Lean, I suggest you start with easier material. Like the Natural Number Game:
https://adam.math.hhu.de/#/g/hhu-adam/NNG4

HenrikT (Jun 01 2023 at 21:58):

i did not know there was a LEAN4 version i only found the Lean3 version

HenrikT (Jun 01 2023 at 21:58):

ill have a look at it

Martin Dvořák (Jun 01 2023 at 21:59):

NNG4 is pretty new!

HenrikT (Jun 01 2023 at 22:02):

Ok guess i play abit arond in NNG4. If anything else pops up regarding the proof ill let you know

Martin Dvořák (Jun 01 2023 at 22:02):

HenrikT said:

I defined it in the same file.
(...)

FYI, I didn't check whether your definitions make sense as a Turing machine. I was just treating it as a black box.

If you really want to play with Turing machines, I suggest that (before you do any theorems) you define an example and check whether you can walk through its computation in the way you intended.

HenrikT (Jun 01 2023 at 22:05):

ok :+1:


Last updated: Dec 20 2023 at 11:08 UTC