
(* SequencePosition.m	Bruce Smith	6 Dec 89, 29 Apr 90, 25 Jun 90 *)

Begin["System`"]

SequencePosition::usage = "SequencePosition[sequence, pattern] gives a list
of the positions of the subsequences of sequence which match pattern.
The positions are in the form
{index of first element, index of last element},
which is a standard sequence specification acceptable to Take or Drop."

FirstSequencePosition::usage = "FirstSequencePosition[sequence, pattern]
gives the position of the first subsequence of sequence which matches
pattern, or Null if there is no such subsequence.
The position is in the form
{index of first element, index of last element},
which is a standard sequence specification acceptable to Take or Drop."

SequencePosition::pattern = FirstSequencePosition::pattern =
"Pattern `1` in `2` must be a list (for example, {_Integer, __Real})."

Begin["`Private`"]

(*
Unprotect[SequencePosition, FirstSequencePosition]
Clear[SequencePosition, FirstSequencePosition]
*)

SequencePosition[seq_,{pat___}] :=
    Module[{flattenme}, Module[{res = flattenme[], seqlen = Length[seq]},
	Replace[seq, _[a___,pat,b___] -> Null /;
		(res = flattenme[res, {1+Length[Hold[a]],
				seqlen - Length[Hold[b]] }];
		 False) ];
	Apply[List, Flatten[res, Infinity, flattenme]]
]]

e:SequencePosition[seq_, otherpat_] := e /; (
	With[{h = Head[Unevaluated[e]]},
		Message[h::pattern, otherpat, Unevaluated[e]]];
	True
	)

e:SequencePosition[a___ /; Length[Hold[a]] != 2] := e /; (
	With[{h = Head[Unevaluated[e]]},
		Message[h::argct, h, Unevaluated[e],
			Length[Unevaluated[e]] ] ];
	True
	)

FirstSequencePosition[seq_,{pat___}] :=
    Module[{res = Null, seqlen = Length[seq]},
	Replace[seq, _[a___,pat,b___] -> Null /;
		(Set[res, {1+Length[Hold[a]],
				seqlen - Length[Hold[b]] }];
		 True) ];
	res
]

e:FirstSequencePosition[seq_, otherpat_] := e /; (
	With[{h = Head[Unevaluated[e]]},
		Message[h::pattern, otherpat, Unevaluated[e]]];
	True
	)

e:FirstSequencePosition[a___ /; Length[Hold[a]] != 2] := e /; (
	With[{h = Head[Unevaluated[e]]},
		Message[h::argct, h, Unevaluated[e],
			Length[Unevaluated[e]] ] ];
	True
	)

Protect[SequencePosition, FirstSequencePosition]
End[]
End[]

Null
