the variance of the stochastic gradient computed by the i_th client is bounded by $$ \sigma^2 $$ - statistics

The stochastic gradient $$ \nabla F_i (\omega, \Eta_i) $$ computed by the i_th client at model parameter $$ \omega $$ with minibatch $$Eta $$ has variance bounded by $$\sigma^2 $$.
E [ || \sum_{k=0}^{K-1} g_{i,k}^r ||^2 ] \leq K sum_{k=0}^{K-1} E [|| \nabla F_i (\omega_{r,k}^i) ||^2] + (K L^2 \rho ^2 \sigma_l ^2)/ N $$
The proof of the statement above was already done in the paper. I just couldn't understand the point of it. I would appreciate any hint on how the proof was completed. The proof can be found below:
$$ E [ || \sum_{k=0}^{K-1} g_{i,k}^r ||^2 ] = E [ || \sum_{k=0}^{K-1} g_{i,k}^r ||^2 ] + E[ || sum_{k=0}^{K-1} (g_{i,k}^r - \nabla F(w_{i,k}^r)) ||^2 ]
\leq K \sum_{k=0}^{K-1} E [|| g_{i,k}^r ||^2] + L^2 \sum_{k=0}^{K-1} E[ || 1/N \sum (\omega_{i,k}^r + \delta_{i,k}^r (\tilde(\omega_{i,k}^r); \Eta_{i,k}^r) - \omega_{i,k}^r - \delta_{i,k}^r (\tilde(\omega_{i,k}^r) ) ||^2 ]
\leq K \sum_{k=0}^{K-1} E [|| g_{i,k}^r ||^2] (KL^2 \rho ^2 \sigma_l ^2)/ N $$
I don't understand how the first step of the proof was made

Related

Get If (condition), then (assign value), else (assign other value) statement in Linear Programming

I'm looking for a linear programming equation that satisfied the conditions;
Given that all variables here are binary variables
if A+B = 2; then C = 1; else C = 0
Also,
if A+B+D = 3; then E = 1; else E = 0
How would one phrase this and satisfy these conditions as well as linearity conditions?
I've tried
A + B - 2 <= M(1-y) and 1 - C <= My
for the first constraint but it doesn't seem to work
For the first equation, you can use:
C + 1 >= A + B
2C <= A + B
If there is a natural sense (max/min) for C in the problem, one of those is sufficient.
Similarly for the second:
E + 2 >= A + B + D
3E <= A + B + D

Jags gets wired, returns redefining node errer occasionally, due to different data

I created my code based on this :
http://users.aims.ac.za/~mackay/BUGS/Manual05/Examples1/node29.html
Now I use different seeds to simulate data. It is strange enough that some seeds give me a redefining node dN[1,1] on line 18 error, while others do not. Could someone help please? BTW why is dN[1,1] on line 18 at the first place? How does Jags count lines?
error message :
"
RUNTIME ERROR:
Compilation error on line 18.
Attempt to redefine node dN[1,1]
"
bugsmodel <- "
# Set up data
data{
for(i in 1:N)
{
for(j in 1:bigt)
{
Y[i,j] <- step(obs.t[i] - t[j] + eps)
dN[i, j] <- Y[i, j] * step(t[j + 1] - obs.t[i] - eps) * fail[i]
}
}
}
# Model
model
{
for(i in 1:N){
betax[i,1] <- 0
for(k in 2:(p+1)){
betax[i,k] <- betax[i,k-1] + beta[k-1]*x[i,k-1]
}
}
for(j in 1:bigt) {
for(i in 1:N) {
dN[i, j] ~ dpois(Idt[i, j]) # Likelihood
Idt[i, j] <- Y[i, j] * exp(betax[i,p+1]) * dL0[j] # Intensity
}
dL0[j] ~ dgamma(mu[j], c)
mu[j] <- dL0.star[j] * c # prior mean hazard
}
c <- 0.001
r <- 0.1
for (j in 1 : bigt) {
dL0.star[j] <- r * (t[j + 1] - t[j])
}
for(k in 1:p){
beta[k] ~ dnorm(0.0,0.000001)
}
}"

CTL fomula until contains implication

when I use NuSMV tools to verify if my CTL is right, I encounter a problem that make me so confused.
My model is
and here's the NuSMV code:
MODULE main
VAR
state : {ROOT, A1, B1, C1, D1, F1, M1};
ASSIGN
init(state) := ROOT;
next(state) := case
state = ROOT : A1;
state = A1 : {B1, C1};
state = B1 : D1;
state = D1 : F1;
TRUE : state;
esac;
CTLSPEC
AG( state=A1 -> AX ( A [ state=B1 U ( state=D1 -> EX state=F1 ) ] ) );
CTLSPEC
AG( state=A1 -> AX ( A [ state=B1 U ( state=F1 -> EX state=C1 ) ] ) );
CTLSPEC
AG( state=A1 -> AX ( A [ state=M1 U ( state=F1 -> EX state=C1 ) ] ) );
My CTL formula is as follows:
"AG( A1 -> AX ( A [ B1 U ( D1 -> EX ( F1) ) ] ) )"
"AG( A1 -> AX ( A [ B1 U ( F1 -> EX ( C1) ) ] ) )"
"AG( A1 -> AX ( A [ M1 U ( F1 -> EX ( C1) ) ] ) )"
NuSMV verified the above three formulas all of which turns out to be true .
So my question is that why the formula 2 and formula 3 turn out to be true?
This question is old, but I think it's still worth an answer, as the issue might be misleading for other people.
M, s ⊨ A[ϕUψ] iff for all paths (s, s2,s3, s4, . ..) s.t. si Rt si+1 there is a state sj s.t. M, sj ⊨ ψ and M, si ⊨ ϕ for all i < j.
So, for the property to be verified, ϕ must be true up until when ψ fires.
Notice that if ψ fires immediately then the value of ϕ is not relevant.
It is easy to see that all three formulas are trivially verified because ψ is true in the first state of each path starting from B1 and C1.
This is the case because ψ is an implication which, in states B1 and C1, has a false premise.
Since we know that A [ ANYTHING U TRUE ] is verified for any state, we conclude that all three properties are satisfiable.

How to solve 15-puzzle paradigm in Prolog with Manhattan & Hamming Heuristics

I have this implementation of the 15-puzzle game, using Prolog (Swipl). I have already implemented the A* search using Manhattan heuristic, but now I need to add hamming heuristic.
Do yo know how to implement it?
:- op(400,yfx,'#').
resolver(Estado,MovimientosSolucion) :- evaluar(Estado,0,F),
buscarSolucion([Estado#0#F#[]],S), reverse(S,MovimientosSolucion).
evaluar(Estado,Profundidad,F) :- evaluarCoste(Estado,Coste),
F is Profundidad + Coste.
buscarSolucion([Estado#_#_#MovimientosSolucion|_], MovimientosSolucion) :- solucion(Estado).
buscarSolucion([B|R],S) :- expandir(B,Sucesores),
insertarTodos(Sucesores,R,ListaAbiertos),
buscarSolucion(ListaAbiertos,S).
insertarUno(B,ListaAbiertos,ListaAbiertos) :- nodoRepetido(B,ListaAbiertos), ! .
insertarUno(B,[C|R],[B,C|R]) :- costeMenor(B,C), ! .
insertarUno(B,[B1|R],[B1|S]) :- insertarUno(B,R,S), !.
insertarUno(B,[],[B]).
insertarTodos([F|R],ListaAbiertos1,ListaAbiertos2) :- insertarUno(F,ListaAbiertos1,ListaAbiertos3),
insertarTodos(R,ListaAbiertos3,ListaAbiertos2).
insertarTodos([],ListaAbiertos,ListaAbiertos).
nodoRepetido(Estado#_#_#_, [Estado#_#_#_|_]).
costeMenor( _#_#F1#_ , _#_#F2#_ ) :- F1 < F2.
expandir(Estado#Profundidad#_#S,Sucesores) :- findall(Sucesor#Profundidad1#F#[Movimiento|S],
(Profundidad1 is Profundidad+1,
mover(Estado,Sucesor,Movimiento),
evaluar(Sucesor,Profundidad1,F)), Sucesores).
solucion(1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/0).
manhattan(A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P, Coste) :- a(A,CosteA), b(B,CosteB), c(C,CosteC), d(D, CosteD),
e(E,CosteE), f(F,CosteF), g(G,CosteG), h(H,CosteH),
i(I,CosteI), j(J,CosteJ), k(K,CosteK), l(L,CosteL),
m(M,CosteM), n(N,CosteN), o(O,CosteO), p(P,CosteP),
Coste is CosteA + CosteB + CosteC + CosteD + CosteE + CosteF + CosteG + CosteH + CosteI + CosteJ + CosteK + CosteL + CosteM + CosteN + CosteO + CosteP.
evaluarCoste(Tablero,Coste) :- hamming_distance(Tablero,Coste).
mover(TableroInicial,TableroFinal,moverArriba) :- moverArriba(TableroInicial,TableroFinal).
mover(TableroInicial,TableroFinal,moverAbajo) :- moverAbajo(TableroInicial,TableroFinal).
mover(TableroInicial,TableroFinal,moverDerecha) :- moverDerecha(TableroInicial,TableroFinal).
mover(TableroInicial,TableroFinal,moverIzquierda) :- moverIzquierda(TableroInicial,TableroFinal).
moverArriba(A/B/C/D/0/F/G/H/I/J/K/L/M/N/O/P,0/B/C/D/A/F/G/H/I/J/K/L/M/N/O/P).
moverArriba(A/B/C/D/E/0/G/H/I/J/K/L/M/N/O/P,A/0/C/D/E/B/G/H/I/J/K/L/M/N/O/P).
moverArriba(A/B/C/D/E/F/0/H/I/J/K/L/M/N/O/P,A/B/0/D/E/F/C/H/I/J/K/L/M/N/O/P).
moverArriba(A/B/C/D/E/F/G/0/I/J/K/L/M/N/O/P,A/B/C/0/E/F/G/D/I/J/K/L/M/N/O/P).
moverArriba(A/B/C/D/E/F/G/H/0/J/K/L/M/N/O/P,A/B/C/D/0/F/G/H/E/J/K/L/M/N/O/P).
moverArriba(A/B/C/D/E/F/G/H/I/0/K/L/M/N/O/P,A/B/C/D/E/0/G/H/I/F/K/L/M/N/O/P).
moverArriba(A/B/C/D/E/F/G/H/I/J/0/L/M/N/O/P,A/B/C/D/E/F/0/H/I/J/G/L/M/N/O/P).
moverArriba(A/B/C/D/E/F/G/H/I/J/K/0/M/N/O/P,A/B/C/D/E/F/G/0/I/J/K/H/M/N/O/P).
moverArriba(A/B/C/D/E/F/G/H/I/J/K/L/0/N/O/P,A/B/C/D/E/F/G/H/0/J/K/L/I/N/O/P).
moverArriba(A/B/C/D/E/F/G/H/I/J/K/L/M/0/O/P,A/B/C/D/E/F/G/H/I/0/K/L/M/J/O/P).
moverArriba(A/B/C/D/E/F/G/H/I/J/K/L/M/N/0/P,A/B/C/D/E/F/G/H/I/J/0/L/M/N/K/P).
moverArriba(A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/0,A/B/C/D/E/F/G/H/I/J/K/0/M/N/O/L).
moverAbajo(0/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P,E/B/C/D/0/F/G/H/I/J/K/L/M/N/O/P).
moverAbajo(A/0/C/D/E/F/G/H/I/J/K/L/M/N/O/P,A/F/C/D/E/0/G/H/I/J/K/L/M/N/O/P).
moverAbajo(A/B/0/D/E/F/G/H/I/J/K/L/M/N/O/P,A/B/G/D/E/F/0/H/I/J/K/L/M/N/O/P).
moverAbajo(A/B/C/0/E/F/G/H/I/J/K/L/M/N/O/P,A/B/C/H/E/F/G/0/I/J/K/L/M/N/O/P).
moverAbajo(A/B/C/D/0/F/G/H/I/J/K/L/M/N/O/P,A/B/C/D/I/F/G/H/0/J/K/L/M/N/O/P).
moverAbajo(A/B/C/D/E/0/G/H/I/J/K/L/M/N/O/P,A/B/C/D/E/J/G/H/I/0/K/L/M/N/O/P).
moverAbajo(A/B/C/D/E/F/0/H/I/J/K/L/M/N/O/P,A/B/C/D/E/F/K/H/I/J/0/L/M/N/O/P).
moverAbajo(A/B/C/D/E/F/G/0/I/J/K/L/M/N/O/P,A/B/C/D/E/F/G/L/I/J/K/0/M/N/O/P).
moverAbajo(A/B/C/D/E/F/G/H/0/J/K/L/M/N/O/P,A/B/C/D/E/F/G/H/M/J/K/L/0/N/O/P).
moverAbajo(A/B/C/D/E/F/G/H/I/0/K/L/M/N/O/P,A/B/C/D/E/F/G/H/I/N/K/L/M/0/O/P).
moverAbajo(A/B/C/D/E/F/G/H/I/J/0/L/M/N/O/P,A/B/C/D/E/F/G/H/I/J/O/L/M/N/0/P).
moverAbajo(A/B/C/D/E/F/G/H/I/J/K/0/M/N/O/P,A/B/C/D/E/F/G/H/I/J/K/P/M/N/O/0).
moverDerecha(0/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P,B/0/C/D/E/F/G/H/I/J/K/L/M/N/O/P).
moverDerecha(A/0/C/D/E/F/G/H/I/J/K/L/M/N/O/P,A/C/0/D/E/F/G/H/I/J/K/L/M/N/O/P).
moverDerecha(A/B/0/D/E/F/G/H/I/J/K/L/M/N/O/P,A/B/D/0/E/F/G/H/I/J/K/L/M/N/O/P).
moverDerecha(A/B/C/D/0/F/G/H/I/J/K/L/M/N/O/P,A/B/C/D/F/0/G/H/I/J/K/L/M/N/O/P).
moverDerecha(A/B/C/D/E/0/G/H/I/J/K/L/M/N/O/P,A/B/C/D/E/G/0/H/I/J/K/L/M/N/O/P).
moverDerecha(A/B/C/D/E/F/0/H/I/J/K/L/M/N/O/P,A/B/C/D/E/F/H/0/I/J/K/L/M/N/O/P).
moverDerecha(A/B/C/D/E/F/G/H/0/J/K/L/M/N/O/P,A/B/C/D/E/F/G/H/J/0/K/L/M/N/O/P).
moverDerecha(A/B/C/D/E/F/G/H/I/0/K/L/M/N/O/P,A/B/C/D/E/F/G/H/I/K/0/L/M/N/O/P).
moverDerecha(A/B/C/D/E/F/G/H/I/J/0/L/M/N/O/P,A/B/C/D/E/F/G/H/I/J/L/0/M/N/O/P).
moverDerecha(A/B/C/D/E/F/G/H/I/J/K/L/0/N/O/P,A/B/C/D/E/F/G/H/I/J/K/L/N/0/O/P).
moverDerecha(A/B/C/D/E/F/G/H/I/J/K/L/M/0/O/P,A/B/C/D/E/F/G/H/I/J/K/L/M/O/0/P).
moverDerecha(A/B/C/D/E/F/G/H/I/J/K/L/M/N/0/P,A/B/C/D/E/F/G/H/I/J/K/L/M/N/P/0).
moverIzquierda(A/0/C/D/E/F/G/H/I/J/K/L/M/N/O/P,0/A/C/D/E/F/G/H/I/J/K/L/M/N/O/P).
moverIzquierda(A/B/0/D/E/F/G/H/I/J/K/L/M/N/O/P,A/0/B/D/E/F/G/H/I/J/K/L/M/N/O/P).
moverIzquierda(A/B/C/0/E/F/G/H/I/J/K/L/M/N/O/P,A/B/0/C/E/F/G/H/I/J/K/L/M/N/O/P).
moverIzquierda(A/B/C/D/E/0/G/H/I/J/K/L/M/N/O/P,A/B/C/D/0/E/G/H/I/J/K/L/M/N/O/P).
moverIzquierda(A/B/C/D/E/F/0/H/I/J/K/L/M/N/O/P,A/B/C/D/E/0/F/H/I/J/K/L/M/N/O/P).
moverIzquierda(A/B/C/D/E/F/G/0/I/J/K/L/M/N/O/P,A/B/C/D/E/F/0/G/I/J/K/L/M/N/O/P).
moverIzquierda(A/B/C/D/E/F/G/H/I/0/K/L/M/N/O/P,A/B/C/D/E/F/G/H/0/I/K/L/M/N/O/P).
moverIzquierda(A/B/C/D/E/F/G/H/I/J/0/L/M/N/O/P,A/B/C/D/E/F/G/H/I/0/J/L/M/N/O/P).
moverIzquierda(A/B/C/D/E/F/G/H/I/J/K/0/M/N/O/P,A/B/C/D/E/F/G/H/I/J/0/K/M/N/O/P).
moverIzquierda(A/B/C/D/E/F/G/H/I/J/K/L/M/0/O/P,A/B/C/D/E/F/G/H/I/J/K/L/0/M/O/P).
moverIzquierda(A/B/C/D/E/F/G/H/I/J/K/L/M/N/0/P,A/B/C/D/E/F/G/H/I/J/K/L/M/0/N/P).
% coste en distancias de cada posicion
a(0,6). a(1,0). a(2,1). a(3,2). a(4,3). a(5,1). a(6,2). a(7,3). a(8,4). a(9,2). a(10,3). a(11,4). a(12,5). a(13,3). a(14,4). a(15,5).
b(0,5). b(1,1). b(2,0). b(3,1). b(4,2). b(5,2). b(6,1). b(7,2). b(8,3). b(9,3). b(10,2). b(11,3). b(12,4). b(13,4). b(14,3). b(15,4).
c(0,4). c(1,2). c(2,1). c(3,0). c(4,1). c(5,3). c(6,2). c(7,1). c(8,2). c(9,4). c(10,3). c(11,2). c(12,3). c(13,5). c(14,4). c(15,3).
d(0,3). d(1,3). d(2,2). d(3,1). d(4,0). d(5,4). d(6,3). d(7,2). d(8,1). d(9,5). d(10,4). d(11,3). d(12,2). d(13,6). d(14,5). d(15,4).
e(0,5). e(1,1). e(2,2). e(3,3). e(4,4). e(5,0). e(6,1). e(7,2). e(8,3). e(9,1). e(10,2). e(11,3). e(12,4). e(13,2). e(14,3). e(15,4).
f(0,4). f(1,2). f(2,1). f(3,2). f(4,3). f(5,1). f(6,0). f(7,1). f(8,2). f(9,2). f(10,1). f(11,2). f(12,3). f(13,3). f(14,2). f(15,3).
g(0,3). g(1,3). g(2,2). g(3,1). g(4,2). g(5,2). g(6,1). g(7,0). g(8,1). g(9,3). g(10,2). g(11,1). g(12,2). g(13,4). g(14,3). g(15,2).
h(0,2). h(1,4). h(2,3). h(3,2). h(4,1). h(5,3). h(6,2). h(7,1). h(8,0). h(9,4). h(10,3). h(11,2). h(12,1). h(13,5). h(14,4). h(15,3).
i(0,4). i(1,2). i(2,3). i(3,4). i(4,5). i(5,1). i(6,2). i(7,3). i(8,4). i(9,0). i(10,1). i(11,2). i(12,3). i(13,1). i(14,2). i(15,3).
j(0,3). j(1,3). j(2,2). j(3,3). j(4,4). j(5,2). j(6,1). j(7,2). j(8,3). j(9,1). j(10,0). j(11,1). j(12,2). j(13,2). j(14,1). j(15,2).
k(0,2). k(1,4). k(2,3). k(3,2). k(4,3). k(5,3). k(6,2). k(7,1). k(8,2). k(9,2). k(10,1). k(11,0). k(12,1). k(13,3). k(14,2). k(15,1).
l(0,1). l(1,5). l(2,4). l(3,3). l(4,2). l(5,4). l(6,3). l(7,2). l(8,1). l(9,3). l(10,2). l(11,1). l(12,0). l(13,4). l(14,3). l(15,2).
m(0,3). m(1,3). m(2,4). m(3,5). m(4,6). m(5,2). m(6,3). m(7,4). m(8,5). m(9,1). m(10,2). m(11,3). m(12,4). m(13,0). m(14,1). m(15,2).
n(0,2). n(1,4). n(2,3). n(3,4). n(4,5). n(5,3). n(6,2). n(7,3). n(8,4). n(9,2). n(10,1). n(11,2). n(12,3). n(13,1). n(14,0). n(15,1).
o(0,1). o(1,5). o(2,4). o(3,3). o(4,4). o(5,4). o(6,3). o(7,2). o(8,3). o(9,3). o(10,2). o(11,1). o(12,2). o(13,2). o(14,1). o(15,0).
p(0,0). p(1,6). p(2,5). p(3,4). p(4,3). p(5,5). p(6,4). p(7,3). p(8,2). p(9,4). p(10,3). p(11,2). p(12,1). p(13,3). p(14,2). p(15,1).
Thanks a lot
Here is the solver for 8-puzzle, extended... maybe it will use too much memory. It implements simply a greedy heuristic. Could be interesting to extend it with A*...
/* File: fifteen_puzzle.pl
Author: Carlo,,,
Created: Jul 9 2014
Purpose: solve 15-puzzle
*/
:- module(fifteen_puzzle,
[fifteen_puzzle/3
]).
:- use_module(library(nb_set)).
:- use_module(library(plunit)).
%% fifteen_puzzle(+Target, +Start, -Moves) is nondet.
%
% public interface to solver
%
fifteen_puzzle(Target, Start, Moves) :-
empty_nb_set(E),
solve(E, Target, Start, Moves).
%% -- private here --
solve(_, Target, Target, []) :-
!.
solve(S, Target, Current, [Move|Ms]) :-
add_to_seen(S, Current),
setof(Dist-M-Update,
( get_move(Current, P, M),
apply_move(Current, P, M, Update),
distance(Target, Update, Dist)
), Moves),
member(_-Move-U, Moves),
solve(S, Target, U, Ms).
%% get_move(+Board, +P, -Q) is semidet
%
% based only on coords, get next empty cell
%
get_move(Board, P, Q) :-
nth0(P, Board, 0),
coord(P, R, C),
( R < 3, Q is P + 4
; R > 0, Q is P - 4
; C < 3, Q is P + 1
; C > 0, Q is P - 1
).
%% apply_move(+Current, +P, +M, -Update)
%
% swap elements at position P and M
%
apply_move(Current, P, M, Update) :-
assertion(nth0(P, Current, 0)), % constrain to this application usage
( P > M -> (F,S) = (M,P) ; (F,S) = (P,M) ),
nth0(S, Current, Sv, A),
nth0(F, A, Fv, B),
nth0(F, C, Sv, B),
nth0(S, Update, Fv, C).
%% coord(+P, -R, -C)
%
% from linear index to row, col
% size fixed to 4*4
%
coord(P, R, C) :-
R is P // 4,
C is P mod 4.
%% distance(+Current, +Target, -Dist)
%
% compute Manatthan distance between equals values
%
distance(Current, Target, Dist) :-
aggregate_all(sum(D),
( nth0(P, Current, N), coord(P, Rp, Cp),
nth0(Q, Target, N), coord(Q, Rq, Cq),
D is abs(Rp - Rq) + abs(Cp - Cq)
), Dist).
%% add_to_seen(+S, +Current)
%
% fail if already in, else store
%
add_to_seen(S, L) :-
%term_to_atom(L, A),
findall(C, (nth0(I, L, D), C is D*10^I), Cs),
sum_list(Cs, A),
add_nb_set(A, S, true).
:- begin_tests(fifteen_puzzle).
show_square(R) :-
findall(Row, (between(1,4,_), length(Row, 4)), Rows),
append(Rows, R),
nl, maplist(show_row, Rows).
show_row(R) :-
format('~t~d~3+~t~d~3+~t~d~3+~t~d~3+~n', R).
show_solution(P, []) :-
show_square(P).
show_solution(P, [M|Ms]) :-
show_square(P),
nth0(C, P, 0),
apply_move(P, C, M, U),
show_solution(U, Ms).
target( [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0]).
start(0, [1,2,3,4,5,6,7,8,9,10,11,12,0,13,14,15]).
start(1, [1,2,3,4,5,6,7,8,0,10,11,12,9,13,14,15]).
test(0) :- runtest(0).
test(1) :- runtest(1).
runtest(N) :-
target(T),
start(N, S),
fifteen_puzzle(T, S, R),
format('solution of ~d: ~w~n', [N, R]),
show_solution(S, R).
:- end_tests(fifteen_puzzle).
you can use ?- run_tests(fifteen_puzzle). for a simple test.

R remove redundant parentheses from formula string or expression

I have many formula strings similar to this:
str <- "( (( A ) * J ) - (( J ) * G ) ) / Z "
There are many parentheses which don't need to be there, (A*J - J*G)/Z is sufficient. Is there a function or package in R that can take care of this?
I tried functions for R expressions and as well as.formula but did not find what I need.
We can use R parser to do the job. The trick is that R knows when parentheses are needed based on the parse tree, so we can simply remove them from the tree:
See this:
simplify <- function(e)
{
if( mode(e) %in% c("name","numeric") ) return(e)
op <- as.character(e[[1]])
if( op == "(" ) return(simplify(e[[2]]))
if( op %in% c("+","-","*","/","^") ) return(call(op, simplify(e[[2]]), simplify(e[[3]])))
}
simplifytext <- function(s) deparse(simplify(parse(text=s)[[1]]))
Inputs:
str <- "( (( A ) * J ) - (( J ) * G ) ) / Z "
str2 <- gsub("-", "/", gsub("*", "+", str, fixed=TRUE))
Results:
> str2
[1] "( (( A ) + J ) / (( J ) + G ) ) / Z "
> simplifytext(str)
[1] "(A * J - J * G)/Z"
> simplifytext(str2)
[1] "(A + J)/(J + G)/Z"
Here are a couple of approaches:
R parsing
rmParen <- function(e) {
if (length(e) > 1) {
if (identical(e[[1]], as.symbol("("))) e <- e[[2]]
if (length(e) > 1) for (i in 1:length(e)) e[[i]] <- Recall(e[[i]])
}
e
}
s <- "( (( A ) * J ) - (( J ) * G ) ) / Z "
rmParen(parse(text = s)[[1]])
The last line returns:
(A * J - J * G)/Z
This works in all cases I tried but you might want to test it out a bit more.
If you want a character string as the return value then use deparse as in deparse(rmParen(parse(text = s)[[1]])). Note that deparse has a width.cutoff argument which is set to 60 by default but can be set to be larger if the actual expressions exceed that length.
Ryacas
library(Ryacas)
s <- "( (( A ) * J ) - (( J ) * G ) ) / Z "
Simplify(s)
The last line returns:
expression((A - G) * J/Z)
Note that its actually the print method that invokes the computation so if you want to save it then try yacas(Simplify(s))$text or as.character(yacas(Simplify(s))) .
ADDED: Ryacas solution.

Resources