AHK Parse multiple xml elements in sequence into [.txt] file - xml-parsing

I've gotten to where I can get the element values I want and append them to a txt file. The problem I'm having is appending them sequentially. An excerpt/sample from my xml file is:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Arcade>
<Game>
<Title>t1</Title>
<Publisher>p1</Publisher>
<Source>s1</Source>
<Version>v1</Version>
<Genre>g1</Genre>
</Game>
<Game>
<Title>t2</Title>
<Publisher>p2</Publisher>
<Source>s2</Source>
<Version>v2</Version>
<Genre>g2</Genre>
</Game>
<Game>
<Title>t3</Title>
<Publisher>p3</Publisher>
<Source>s3</Source>
<Version>v3</Version>
<Genre>g3</Genre>
</Game>
</Arcade>
The output I would like to see is:
t1 s1 g1
t2 s2 g2
t3 s3 g3
My baseline script:
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
xmlPath := "D:\temp\Arcade.xml"
xmlDoc := ComObjCreate("MSXML2.DOMDocument.6.0")
xmlDoc.async := false
xmlDoc.load(xmlPath)
Loop Files, %xmlPath%
{
for item in xmlDoc.getElementsByTagName("Title") {
Tstring := item.text
FileAppend, %Tstring% , D:\temp\testoutput.txt
}
for item in xmlDoc.getElementsByTagName("Source") {
Sstring := item.text
FileAppend, %Sstring% , D:\temp\testoutput.txt
}
for item in xmlDoc.getElementsByTagName("Genre") {
Gstring := item.text
FileAppend, %Gstring%`n, D:\temp\testoutput.txt
}
ExitApp
}
Which results in:
t1 t2 t3 s1 s2 s3
g1
g2
g3
I've tried moving the close 'curly brackets' around and also the FileAppend similar to:
Loop Files, %xmlPath%
{
for item in xmlDoc.getElementsByTagName("Title") {
Tstring := item.text
for item in xmlDoc.getElementsByTagName("Source") {
Sstring := item.text
for item in xmlDoc.getElementsByTagName("Genre") {
Gstring := item.text
FileAppend, %Tstring%|%Sstring%|%Gstring%`n, D:\temp\testoutput.txt
}
}
}
ExitApp
}
..which gives me:
t1 s1 g1
t1 s1 g2
t1 s1 g3
t1 s2 g1
t1 s2 g2
t1 s2 g3
t1 s3 g1
t1 s3 g2
t1 s3 g3
t2 s1 g1
t2 s1 g2
t2 s1 g3
...
And a few other iterations. I know (or at least feel) I'm on the right track and if this were the MasterMind game, I think I might have it by now. :) Alas, it's not.
Any help and guidance would be appreciated.

The easiest thing is probably doing it game by game, for example:
for Game in xmlDoc.getElementsByTagName("Game") {
Text := ""
Text .= Game.getElementsByTagName("Title").item(0).text
Text .= Game.getElementsByTagName("Source").item(0).text
Text .= Game.getElementsByTagName("Genre").item(0).text
MsgBox % Text
}

Related

Simple refl-based proof problem in Lean (but not in Agda)

In an attempt to define skew heaps in Lean and prove some results, I have defined a type for trees together with a fusion operation:
inductive tree : Type
| lf : tree
| nd : tree -> nat -> tree -> tree
def fusion : tree -> tree -> tree
| lf t2 := t2
| t1 lf := t1
| (nd l1 x1 r1) (nd l2 x2 r2) :=
if x1 <= x2
then nd (fusion r1 (nd l2 x2 r2)) x1 l1
else nd (fusion (nd l1 x1 l1) r2) x2 l2
Then, even for an extremely simple result such as
theorem fusion_lf : ∀ (t : tree), fusion lf t = t := sorry
I'm stuck. I really have no clue for starting to write this proof. If I start like this:
begin
intro t,
induction t with g x d,
refl,
end
I can use refl for the case where t is lf, but not if it is a nd.
I'm a bit at a lost, since in Agda, it is really easy. If I define this:
data tree : Set where
lf : tree
nd : tree -> ℕ -> tree -> tree
fusion : tree -> tree -> tree
fusion lf t2 = t2
fusion t1 lf = t1
fusion (nd l1 x1 r1) (nd l2 x2 r2) with x1 ≤? x2
... | yes _ = nd (fusion r1 (nd l2 x2 r2)) x1 l1
... | no _ = nd (fusion (nd l1 x1 r1) r2) x2 l2
then the previous result is obtained directly with a refl:
fusion_lf : ∀ t -> fusion lf t ≡ t
fusion_lf t = refl
What I have missed?
This proof works.
theorem fusion_lf : ∀ (t : tree), fusion lf t = t :=
λ t, by cases t; simp [fusion]
If you try #print fusion.equations._eqn_1 or #print fusion.equations._eqn_2 and so on, you can see the lemmas that simp [fusion] will use. The case splits are not exactly the same as the case splits in the pattern matching, because the case splits in the pattern matching actually duplicate the case lf lf. This is why I needed to do cases t. Usually the equation lemmas are definitional equalities, but this time they are not, and honestly I don't know why.

Substitute variable?

I'm trying to substitute L with Lα:
f(x) := c * (x + L);
c: L;
f(x), L: Lα;
I expected the output:
Lα * (x + Lα)
instead I got
L * (x + Lα)
Maybe I should define f(x) instead?
kill(all);
define(
f(x),
c * (x + L)
);
c: L;
f(x), L: Lα;
Nope — same result.
Do I substitute L for Lα in a wrong way?
Edit:
Turns out it is expected behaviour, as maxima evavluates expression only once. One can impose "infinite evaluation" via the flag infeval:
f(x), L: La, infeval;
=> La*(x + La)
Another solution is to use subst instead:
subst(
Lα, L, f(x)
);
(source)
You need to add an extra eval step to make this work:
f(x) := c * (x + L);
c: L;
f(x), L: Lα, eval;
Output:
Lα (x + Lα)
Use subst instead of ev.
(%i1) f(x) := c * (x + L)$
(%i2) c: L$
(%i3) subst(L=La,f(x));
(%o3) La (x + La)
But keep in mind that the function continues to be c*(x+L). The symbol c has been bound to L and if you then bind the symbol L to La, c will continue to be bound to L and not to La. Maxima variables work as in Lisp, which might be different to what you are used to in other languages.

creating multiple variables/lists/functions via a loop (Maxima)

below I have listed some ways to create variables/lists/functions via a for loop in Maxima,
but how, via a for loop, to do:
f1(x) := x^1$
f2(x) := x^2$
f3(x) := x^3$
example code:
for i : 1 thru 10 do
(x : concat ('a, i), x :: i)$
[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
for i : 1 thru 3 do
(x : concat ('L, i), x :: [(3*i)-2,(3*i)-1,3*i])$
[L1, L2, L3];
/* good, but not quite what I want to do */
for i : 1 thru 3 do
f[i](x) := x^i$
[f[1](2), f[2](2), f[3](2)];
/* is there a way, via a for loop, to create */
f1(x) := x^1$
f2(x) := x^2$
f3(x) := x^3$
[f1(2), f2(2), f3(2)];
EDIT: further code:
/* is there a way, via a for loop, to create */
f(x) := x^1$
g(x) := x^2$
h(x) := x^3$
[f(2), g(2), h(2)];
for tmp1 : 1 thru 10 do
(tmp2 : parse_string(ascii(96+tmp1)), tmp2 :: tmp1)$
[a, b, c, d, e, f, g, h, i, j];
for tmp1 : 1 thru 10 do
(tmp2 : concat(parse_string(ascii(96+tmp1)), tmp1), tmp2 :: tmp1)$
[a1, b2, c3, d4, e5, f6, g7, h8, i9, j10];
EDIT 2: original problems solved (any code improvements/simplifications welcome):
for i : 1 thru 3 do
eval_string(concat("f", i, "(x) := x^", i))$
[f1(2), f2(2), f3(2)];
for i : 1 thru 3 do
eval_string(concat(ascii(96+5+i), "(x) := x^", i))$
[f(2), g(2), h(2)];
sum:0$
for i : 1 thru 3 do
sum:sum + eval_string(concat("f", i, "(2)"))$
sum;
sum:0$
for i : 1 thru 3 do
sum:sum + eval_string(concat(ascii(96+5+i), "(2)"))$
sum;
What is your larger goal here? In general using subscripted symbols e.g. a[1] instead of a1 is to be preferred. When you define a subscripted function, you only define it once, not for every value of the subscript. E.g.
(%i1) f[i](x) := x^i $
(%i2) [f[1], f[2], f[3]];
2 3
(%o2) [lambda([x], x), lambda([x], x ), lambda([x], x )]
(%i3) [f[1](u), f[2](v), f[3](w)];
2 3
(%o3) [u, v , w ]
If that doesn't work for you, maybe you can explain about what you're trying to achieve.
I have collected here, various ways of creating multiple variables/lists/functions via a loop in Maxima,
as an answer to the question, '[f1(2), f2(2), f3(2)]' explicitly answers the original question:
for i : 1 thru 10 do
(x : concat ('a, i), x :: i)$
[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
for i : 1 thru 3 do
(x : concat ('L, i), x :: [(3*i)-2,(3*i)-1,3*i])$
[L1, L2, L3];
for tmp1 : 1 thru 10 do
(tmp2 : parse_string(ascii(96+tmp1)), tmp2 :: tmp1)$
[a, b, c, d, e, f, g, h, i, j];
for tmp1 : 1 thru 10 do
(tmp2 : concat(parse_string(ascii(96+tmp1)), tmp1), tmp2 :: tmp1)$
[a1, b2, c3, d4, e5, f6, g7, h8, i9, j10];
for i : 1 thru 3 do
eval_string(concat("f", i, "(x) := x^", i))$
[f1(2), f2(2), f3(2)];
for i : 1 thru 3 do
eval_string(concat(ascii(96+5+i), "(x) := x^", i))$
[f(2), g(2), h(2)];
f[i](x) := x^i$
[f[1], f[2], f[3]];
[f[1](2), f[2](2), f[3](2)];
[f[1](u), f[2](v), f[3](w)];

Definition of normal form in coq

In the book Types and Programing Languages of B. Pierce, the author introduce a small language in order to introduce different concepts used through the book.
The language is the following:
t::=
true
false
if t then t else t
v::=
true
false
There is three reduction rules:
if true then t2 else t3 \rightarrow t2
if false then t2 else t3 \rightarrow t3
t1 \rightarrow t1'
------------------
if t1 then t2 else t3 \rightarrow if t1' then t2 else t3
I would like to prove that every normal form is a value.
I use the following definition for the normal form:
Definition normal_form (t:term) :=
~(exists t', step t t').
I'm stuck because at one point, I have something that looks like :
~ ~(exists t : term, ...)
and I don't see how I can infer
exists t : term, ...
since we are in a intuitionistic logic.
Here is the whole proof:
Inductive term : Set :=
| true : term
| false : term
| ifthenelse : term -> term -> term -> term.
Definition normal_form (t:term) :=
~(exists t', step t t').
Inductive is_value : term -> Prop :=
| vtrue : is_value true
| vfalse : is_value false.
Lemma normal_form_implies_value : forall t, normal_form t -> is_value t.
Proof.
intro.
induction t.
intros.
apply vtrue.
intros.
apply vfalse.
intros.
unfold normal_form in H.
destruct t1.
unfold not in H.
assert (exists t' : term, step(ifthenelse true t2 t3) t').
exists t2.
apply eiftrue.
apply H in H0.
contradiction.
assert (exists t' : term, step(ifthenelse false t2 t3) t').
exists t3.
apply eiffalse.
apply H in H0.
contradiction.
assert(~(is_value (ifthenelse t1_1 t1_2 t1_3))).
intro.
inversion H0.
assert(~(normal_form(ifthenelse t1_1 t1_2 t1_3))).
intro.
apply IHt1 in H1.
contradiction.
unfold normal_form in H1.
unfold not in H1.
Should I use an other definition for the normal form? Is it possible to finish the proof without any classical axiom?
One interesting lemma to prove is the inversion lemma stating that if ifthenelse b l r is in normal form then so are b, l and r.
Lemma normal_form_ifthenelse (b l r : term) :
normal_form (ifthenelse b l r) ->
normal_form b /\ normal_form l /\ normal_form r.
Which can be proven rather easily if you are willing to use a lot of help from the automation machinery.
Proof.
intros H (* assumption "normal_form (ifthenelse b l r)" *)
; repeat split (* split the big conjunction into 3 goals *)
; intros [t redt] (* introduce the "exists t', step t t'" proofs
all the goals are now "False" *)
; apply H (* because we know that "step t t'", we are going to
be able to prove that "step (ifthenelse ...) ..."
which H says is impossible *)
; eexists (* we let Coq guess which term we are going to step to *)
; constructor (* we pick the appropriate constructor between the structural ones *)
; eapply redt. (* finally we lookup the proof we were given earlier *)
Qed.
If that's a bit too much automation for you, you can try to prove manually the following (simpler) lemma because it's the bit we are going to need in the final proof:
Lemma normal_form_ifthenelse (b l r : term) :
normal_form (ifthenelse b l r) -> normal_form b.
Your lemma can then be proven rather quickly: in the two first cases of the induction, using constructor will pick the right is_value constructor.
In the last one, we are provided with an induction hypothesis IHt1 saying that provided that t1 is a normal_form then it is_value. We can use our intermediate lemma to prove that normal_form t1 based on the fact that we know that normal_form (ifthenelse t1 t2 t3) and conclude that is_value t1.
But the fact that t1 is a value contradicts the fact normal_form (ifthenelse t1 t2 t3): we can indeed step to either t2 or t3 depending on whether t1 is true or false. False_ind is a way for us to say "and now we have derived a contradiction".
Lemma normal_form_implies_value : forall t, normal_form t -> is_value t.
Proof.
intro t; induction t; intro ht.
- constructor.
- constructor.
- destruct (normal_form_ifthenelse _ _ _ ht) as [ht1 _].
apply False_ind, ht; destruct (IHt1 ht1); eexists; constructor.
Qed.
is_value is decidable,
Lemma is_value_dec : forall t, {is_value t} + {~is_value t}.
Proof.
induction t;
try (left; constructor);
destruct IHt1;
right; intro C; inversion C.
Qed.
so you can prove normal_form_implies_value by considering those two cases (with destruct), like so:
Lemma normal_form_implies_value : forall t, normal_form t -> is_value t.
Proof.
induction t;
try constructor;
intros;
destruct (is_value_dec t1), t1;
apply False_ind;
apply H;
try (eexists; constructor; fail);
try (inversion i; fail).
contradict n;
apply IHt1;
intros [tt C];
eauto using scomp.
Qed.
scomp is a constructor for step, using this definition:
Inductive step : term -> term -> Prop :=
| strue: forall t1 t2, step (ifthenelse true t1 t2) t1
| sfalse: forall t1 t2, step (ifthenelse false t1 t2) t2
| scomp: forall t1 t1' t2 t3, step t1 t1' ->
step (ifthenelse t1 t2 t3) (ifthenelse t1' t2 t3).

Why is this grammar not LL(1)

I have the next grammar:
C := (PZ)
P := X | C
X := iQ | eQ | rQ
Q := AX | ε
A := +
L := >
Z := LP | AP | ε
and i am using JFLAP to build an LL(1) parsing table, but at the moment that i type those rules, JFLAP throws me an error that says: the grammar is not LL(1).I have found where the mistake is, in the rule 'Q'.
The first set of Q is Q = {+,ε}, and the follow set of Q is Q = { ), + , >} and in the parsing table i am going to have two rules in table[Q,+] and that´s the mistake, but i dont know how to fix it because i need to have the rule Q -> ε
The basic problem is that your grammar is ambiguous -- you have two nested repeating patterns from your rules for X and Z and both of them can match an i+i fragment. So you need to decide how you want to resolve that ambiguity -- which way should a fragment like i+i match:
PZ PZ
/ \ / \
X ε X AP
/ \ / \ / \
i Q i Q + X
/ \ / / \
A X ε i Q
/ / \ |
+ i Q ε
|
ε
The easiest fix is to make it always match the right example, which you can do by just getting rid of the X/Q repeating pattern:
C := (PZ)
P := X | C
X := i | e | r
A := +
L := >
Z := LP | AP | ε
If you want to always match the left example, you need to disallow + in the Z pattern:
C := (PZ)
P := X | C
X := iQ | eQ | rQ
Q := AX | ε
A := +
L := >
Z := LP | ε

Resources