/- Copyright (c) 2020 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Leonardo de Moura -/ import Lean.Expr namespace Lean namespace Expr @[inline] def app1? (e : Expr) (fName : Name) : Option Expr := if e.isAppOfArity fName 1 then some $ e.appArg! else none @[inline] def app2? (e : Expr) (fName : Name) : Option (Expr × Expr) := if e.isAppOfArity fName 2 then some $ (e.appFn!.appArg!, e.appArg!) else none @[inline] def app3? (e : Expr) (fName : Name) : Option (Expr × Expr × Expr) := if e.isAppOfArity fName 3 then some $ (e.appFn!.appFn!.appArg!, e.appFn!.appArg!, e.appArg!) else none @[inline] def app4? (e : Expr) (fName : Name) : Option (Expr × Expr × Expr × Expr) := if e.isAppOfArity fName 4 then some $ (e.appFn!.appFn!.appFn!.appArg!, e.appFn!.appFn!.appArg!, e.appFn!.appArg!, e.appArg!) else none @[inline] def eq? (p : Expr) : Option (Expr × Expr × Expr) := p.app3? `Eq @[inline] def iff? (p : Expr) : Option (Expr × Expr) := p.app2? `Iff @[inline] def heq? (p : Expr) : Option (Expr × Expr × Expr × Expr) := p.app4? `HEq @[inline] def arrow? : Expr → Option (Expr × Expr) | Expr.forallE _ α β _ => if β.hasLooseBVars then none else some (α, β) | _ => none partial def listLitAux : Expr → List Expr → Option (Expr × List Expr) | e, acc => if e.isAppOfArity `List.nil 1 then some (e.appArg!, acc.reverse) else if e.isAppOfArity `List.cons 3 then listLitAux e.appArg! (e.appFn!.appArg! :: acc) else none def listLit? (e : Expr) : Option (Expr × List Expr) := listLitAux e [] def arrayLit? (e : Expr) : Option (Expr × List Expr) := match e.app2? `List.toArray with | some (_, e) => e.listLit? | none => none /-- Recognize `α × β` -/ def prod? (e : Expr) : Option (Expr × Expr) := e.app2? `Prod end Expr end Lean